class A{}
class B{}
class C{
private Map<A,B> myMap;
}
class Test{
public static void main(String [] args)
{
Map classMap=new HashMap();
classMap.put("myMap","?");
C c = (C) JSONObject.toBean(jsonObject, C.class,classMap);
}
}
I am using "net.sf.json" library for converting json object into java object.Here in class C there is a map, so how to convert it into Java Object. Here jsonObject is a json representation of class C.
My question is how to convert a json object into Java Object if java Object containing Map
I am a beginner, any help will be very thankful.
I have used jackson library and in that when a json is passed to the java code and if you want to parse that json into a java object you need to have a class which contains all the property which are present in the json string.
for example:
jsonString=
{
'firstname':'json',
'lastname':'jack'
}
will be equivalent to a java class which contains both the property as
class A {
String firstname;
String lastname;
}
so if you accept the string from frontend as the object of class A it works
like
public void (A objectofA){
}
and you call this method from front end and pass a json string using json library it will work and have faith in your work.
I don't know how to do it in "net.sf.json"
Try to see how serialization works in "net.sf.json". Probably, you can go from there.
This is how it is done using jackson, (one of the commenters has tried to explain you an approach using this)
//you need to import:
//import org.codehaus.jackson.map.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(c) //--> This gives Json String
I don't think this can work, as JSON cannot represent arbitrary objects as keys in maps. In JSON keys have to be strings. So in your example Map would only work if A was String.
Then you could say:
classMap.put("myMap",B.class);
Related
I am calling an end-point and I get the request body looking like this.
{"page":6,"name":"Fly","myList":["123","657","983","112"]}
So I am Creating an org.json.JSONObject like JSONObject repsonseObj = new JSONObject(repsonse.getBody());
I can now do
(int)repsonseObj.get("page");
(String)repsonseObj.get("name");
I am trying to covert "myList" into a Java ArrayList of String.
I can pull it out using a JSONArray object and use a for-loop to populate an instance of ArrayList.
Also tried something like this below using an ObjectMapper for jackson.databind
myListVar = mapper.readValue((String)repsonse.getString("myList"), new TypeReference<ArrayList<String>>(){});
//That gives an error saying "myList" is not a string. Surely I am missing something here.
I want to keep the sequence of the numbers.
Is there a more elegant solution for this? I tried looking at the StringUtils, ArrayUtils from java.lang. I just can't seem to put my finger on a better solution. Can someone point me in the right direction, thanks.
Actually why don't you parse the whole object instead of just the list?
public class MyClass {
private Integer page;
private String name;
private List<String> myList;
//getters, setters
}
And this parses the JSON to a variable
MyClass myClass = objectMapper.readValue("{\"page\":6,\"name\":\"Fly\",\"myList\":[\"123\",\"657\",\"983\",\"112\"]}", MyClass.class);
EDIT:
As it turned out in the comments you need your properties in the JSON to have different names than in your class. This can be easily achieved by annotating the class properties with #JsonProperty as #Dragos Ionut suggested. Just do the following
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
public class MyClass {
#JsonProperty("page")
private Integer otherNameThanPage;
#JsonProperty("name")
private String otherNameThanName;
#JsonProperty("myList")
private List<String> otherNameThanMyList;
//getters, setters
}
I would like not to define an extra type just to make the json conversion. I am using a library that needs an object as an input and then performs http operations with this data, so I cannot use a hard coded json string as input.
private static final Gson GSON = new Gson();
public static void main(String[] args) {
System.out.println(GSON.toJson(new Object() {
private String email_address = "me#mail.eu";
public String getEmail_address() {return "me#mail.eu"; }
public void setEmail_address(String mail) {email_address = mail; }
}));
}
I tried to remove getter and setter or leave the getter and remove the field but it doesn't work. Anybody knows how to fix this?
Libraries for Json serialization/deseralization like Gson, count on the fact that you have defined your custom object on which you will map the json string. This is because they use reflection on the class to map the fields with the corresponding keys in the json. Without it, it is difficult that they can achieve anything(usable).
Why not define an extra type ? We are not in the 1980s. I would personnally use a DTO. What is Data Transfer Object?
But maybe the answer to you question reside here : Java - Does Google's GSON use constructors?
I have a web project with 2 Java Entities(Lets Say E1,E2) like how mybatis and VO works.
Object structure:
class E1{
String a;
.... n other data members
E2 e2;
}
class E2{
String b;
.... n other data members
}
Is it possible to make a single class in Android project, i.e.
class E1 {
String a;
String b; //This Data member belongs to class E2
}
and parse it with the help of a framework (like Jackson) or I have to write a custom class for that?
My JSON Data will look like this:
{
"E1": {
"a": "some data",
.
.
.
"E2": {
"b": "some data",
.
.
other data
}
}
}
Is there any API which can do this?
I asked this because with my web Application its not just 2 Class but atleast 10 interconnected class and I am not Using them in my android app. So don't wanna replicate the same classes in android app.
Also if you can suggest any other possible way.
It would be a very bad design practice/approach, making things very difficult to debug, error prone and not future proof (think about it, what if you add to one of the 10 classes a field that conflict with another class' field?).
Anyway, if you still want to trick your way out of the correct approach that would be to have 10 classes, I am not aware of any lib that provides you with this feature. You could parse json ==> 10 Java Map, then merge the 10 Map through the Map::putAll method and finally pass the obtained Map that contains all the objects to Jackson.
Your best bet is to use #JsonAnySetter annotation from Jackson library on the receiver POJO.
public class E1{
public String a;
private Map<String, Object> paramMap = new HashMap<>();
#JsonAnyGetter
public Map<String, Object> getParamMap() {
return paramMap;
}
#JsonAnySetter
public void setParamMap(String s, Object o) {
paramMap.put(s, o);
}
}
This will put every unimplemented attributes in a HashMap.
In combination with #JsonAnyGetter, the serialization of the receiver POJO will give the same result as the JSON input.
I have a model object which is initialized with default values. To refresh the content of object I call an web service and get the response and get the content from json object.
I want to check If json response contains the object or not. If it does then call the setter and set the data and if it doesn't then leave then don't set it. I have approx 300 fields in my object. How I can do it with less code. I am listing my current approach.
My Model object is like
public class MyObject {
private String str1 = "Initial Value1";
private String str2 = "Initial Value2";
public void setStr1(String str1)
{
this.str1 = str1;
}
public void setStr2(String str2)
{
this.str2 = str2;
}
public String getStr1(){
return str1;
}
public String getStr2(){
return str2;
}
}
my json response be like
{
"val_one":"New Value1",
"val_two":"New_value2"
}
Now at run time I need to set the value from json response
MyObject myObject = new MyObject();
if(jsonObject.has("val_one"));
myObject.setStr1(jsonObject.get("val_one"));
if(jsonObject.has("val_two"));
myObject.setStr2(jsonObject.get("val_two"));
Now how to do it in a better and efficient
If both sides are using JAVA then why not just use json-io. You can create an object as normal. ie
Animal a = new Aminmal() andimal.setName("bob");
Then use json-io to make it into json -- stream to where ever it needs to be... use json io to change back to object
This can be done using
JsonWriter.objectToJson(Object o);
JsonReader.jsonToJava(String json);
https://code.google.com/p/json-io/
json-io is also extremely light weight and quicker than most if not all other third party json library's that I have used.
That being said if you want to have more control on the output ie.. date conversions etc.. then look at GSON.
https://code.google.com/p/google-gson/
Another option, in addition to the other suggestions is gson. Here the link for gson information.
Essentially the idea with gson being that you define an object to represent the JSON structure that you are receiving. So somewhat like what you have now, you'd just need to change the object attributes to match the names of the JSON fields, ie 'val_one' and 'val_two'.
Then you just need to use gson to create the object from the JSON text, eg:
Gson gson = new GsonBuilder().create();
MyObject json = gson.fromJson(jsonStr, MyObject.class);
Why do you want to take of the object model mapping yourself? If you take spring then you can use the jackson mapper and have it all done for you.
If you don't want to use spring then you still can use jackson2 and let it handle the parsing:
http://wiki.fasterxml.com/JacksonRelease20
I have some difficulties with json deserialization using GSon and I hope somebody can help me.
I want to deserialize the following json snippet:
{
"fieldA": "valueA",
"myCollection": {
"AnotherClass": [
{
"objectAfieldA": "valueB",
"objectAfieldB": "valueC"
},
{
"objectAfieldA": "valueD",
"objectAfieldB": "valueE"
}
]
}
}
the corresponding overall class has following fields:
...
String fieldA;
List<AnotherClass> = new ArrayList<AnotherClass>();
....
Now, my problem is that when I deserialize, using fromJson(jsonSample, resultContainer.class), without the List<T> element, everything is good, but I get a NullPointerException when I include the contained list. I've read about how to deal with collections of generic types and the use of TypeToken, but I can't apply this knowledge when my collection is part of another class…
I really would appreciate any help to solve this.
The solution for deserealizing the unnamed JSON array is quite simple:
List<resultContainer> lres = gson.fromJson(new FileReader("input.json"), new TypeToken<List<resultContainer>>(){}.getType());
When deserializing, you only need to use the TypeToken if the outer-most structure to be deserialized into is a generic collection. This is not the case for the example in the original question. So, use of a TypeToken is unnecessary.
The issue appears to be that the JSON structure does not match the Java structure attempting to be bound to.
The JSON structure defines
an object with two elements
element 1 is a string named "fieldA",
element 2 is an object named "myCollection", which has one element
the one element is an array named "AnotherClass", composed of objects with two elements
element 1 is a string named "objectAfieldA",
element 2 is a string named "objectAfieldB"
So, define a Java data structure to match that, and deserialization will work very simply, without any custom processing necessary. If such a matching Java structure is not provided, then custom deserialization is necessary.
Here is such a working example using the names and types from the original question.
import java.io.FileReader;
import com.google.gson.Gson;
public class Foo
{
public static void main(String[] args) throws Exception
{
Gson gson = new Gson();
resultContainer result = gson.fromJson(new FileReader("input.json"), resultContainer.class);
System.out.println(gson.toJson(result));
}
}
class resultContainer
{
String fieldA;
MyCollectionContainer myCollection;
}
class MyCollectionContainer
{
SomeOtherClass[] AnotherClass;
}
class SomeOtherClass
{
String objectAfieldA;
String objectAfieldB;
}