Getting null pointer while reading the fileds from JSON to POJO - java

I have my json as given below which is coming as string. I want to map only two fields in SEGMENT object ex:(TYPE and UN_NUM) to a pojo. I used the following code which is returning null values.
test.json
{
"TEST": {
"NAME": "PART_TRAN",
"VERSION": "9.0",
"ID": "----",
"SEGMENT": {
"TYPE": "R",
"CLIENT_ID": "----",
"UN_NUM": "UN"
}
}
}
test.java
process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
String data = exchange.getIn().getBody(String.class);
try{
XmlMapper xmlMapper = new XmlMapper();
JsonNode jsonNode = xmlMapper.readTree(data.toString());
ObjectMapper objectMapper = new ObjectMapper();
String value = objectMapper.writeValueAsString(jsonNode);
logger.info("Converting XML to JSON {}" , value);
SEGMENT seg = objectMapper.readValue(value, SEGMENT.class);
Test test = new Test(seg);
logger.info("Test Object {}" , test);
}catch (JsonParseException e){
e.printStackTrace();
}catch (JsonMappingException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
}).
SEGMENT.java
#Data
#JsonIgnoreProperties
public class SEGMENT {
#JsonIgnore
private String TYPE;
#JsonIgnore
private String CLIENT_ID;
#JsonIgnore
private String UN_NUM;
}
Test.java
#Data
public class Test {
private String NAME;
private String VERSION;
private String ID;
private SEGMENT segment;
}
Logs:
: Test Object Test(SEGMENT=SEGMENT(TYPE=null, CLIENT_ID =null,UN_NUM =null))
I just added the SEGMENT class which I'm using to map the json.

There is underscore-java library with methods U.fromJsonMap(json) and U.get(map, path). I am the maintainer of the project.
String jsonData = "{\n"
+ " \"TEST\": {\n"
+ " \"NAME\": \"PART_TRAN\",\n"
+ " \"VERSION\": \"9.0\",\n"
+ " \"ID\": \"----\",\n"
+ " \"SEGMENT\": {\n"
+ " \"TYPE\": \"R\",\n"
+ " \"CLIENT_ID\": \"----\",\n"
+ " \"UN_NUM\": \"UN\"\n"
+ " }"
+ " }"
+ "}";
Map<String, Object> jsonObject = U.fromJsonMap(jsonData);
String type = U.<String>get(jsonObject, "TEST.SEGMENT.TYPE");
String unNum = U.<String>get(jsonObject, "TEST.SEGMENT.UN_NUM");
System.out.println(type);
System.out.println(unNum);
Output:
R
UN

Related

Cannot deserialize instance of `model.UsersPajo` out of START_ARRAY token at [Source: (String)"[UsersPajo{website='hildegard.org'

I can’t understand why deserialization doesn’t work.
public static String readUserFile(String titleFile) {
String pathJSONFile = "src/main/resources/" + titleFile + ".json";
ObjectMapper objectMapper = new ObjectMapper();
File jsonFile = new File(pathJSONFile);
UsersPajo[] usersPajos2= null;
try {
usersPajos2 = objectMapper.readValue(jsonFile, UsersPajo[].class);
System.out.println("_usersPajos2___" + usersPajos2);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String information = Arrays.toString(usersPajos2);
try {
usersPajo = objectMapper.readValue(information, UsersPajo.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
I've already tried various options, but it looks like I'm confused.Here is the mistake.
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of
`model.UsersPajo` out of START_ARRAY token
at [Source: (String)"[UsersPajo{website='hildegard.org', address=Address{zipcode='92998-
3874', geo=Geo{lng='81.1496', lat='-37.3159'}, suite='Apt. 556', city='Gwenborough',
street='Kulas Light'}, phone='1-770-736-8031 x56442', name='Leanne Graham',
company=Company{bs='harness real-time e-markets', catchPhrase='Multi-layered client-server
neural-net', name='Romaguera-Crona'}, id=1, email='Sincere#april.biz', username='Bret'},
UsersPajo{website='anastasia.net', address=Address{zipcode='90566-7771',
geo=Geo{lng='-34.46"[truncated 3643 chars]; line: 1, column: 1]
at
Here is the class model
public class UsersPajo{
private String website;
private Address address;
private String phone;
private String name;
private Company company;
private int id;
private String email;
private String username;
public String getWebsite(){
return website;
}
public Address getAddress(){
return address;
}
public String getPhone(){
return phone;
}
public String getName(){
return name;
}
public Company getCompany(){
return company;
}
public int getId(){
return id;
}
public String getEmail(){
return email;
}
public String getUsername(){
return username;
}
#Override
public String toString() {
return "UsersPajo{" +
"website='" + website + '\'' +
", address=" + address +
", phone='" + phone + '\'' +
", name='" + name + '\'' +
", company=" + company +
", id=" + id +
", email='" + email + '\'' +
", username='" + username + '\'' +
'}';
}
}
My JSON file
[ {
"id" : 1,
"name" : "Leanne Graham",
"username" : "Bret",
"email" : "Sincere#april.biz",
"address" : {
"street" : "Kulas Light",
"suite" : "Apt. 556",
"city" : "Gwenborough",
"zipcode" : "92998-3874",
"geo" : {
"lat" : "-37.3159",
"lng" : "81.1496"
}
},
"phone" : "1-770-736-8031 x56442",
"website" : "hildegard.org",
"company" : {
"name" : "Romaguera-Crona",
"catchPhrase" : "Multi-layered client-server neural-net",
"bs" : "harness real-time e-markets"
}
}, ...
]
I read information from a file and then write it into a string. After that, I want to get my java object from this line using desrialization. Tell me why desirialization does not work? What needs to be fixed
The issue is the following lines of code:
try {
usersPajo = objectMapper.readValue(information, UsersPajo.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
The variable information contains the following:
[UsersPajo{website='hildegard.org', address=Address{zipcode='92998-
3874', geo=Geo{lng='81.1496', lat='-37.3159'}, suite='Apt. 556', city='Gwenborough',
street='Kulas Light'}, phone='1-770-736-8031 x56442', name='Leanne Graham',
company=Company{bs='harness real-time e-markets', catchPhrase='Multi-layered client-server
neural-net', name='Romaguera-Crona'}, id=1, email='Sincere#april.biz', username='Bret'},
UsersPajo{website='anastasia.net', address=Address{zipcode='90566-7771',
geo=Geo{lng='-34.46"....
Which basically is the usersPajos2 mapped to a String. This obviously can't be deserialized into a single UsersPajo instance. So get rid of these lines of code and keep all others:
public static String readUserFile(String titleFile) {
String pathJSONFile = "src/main/resources/" + titleFile + ".json";
ObjectMapper objectMapper = new ObjectMapper();
File jsonFile = new File(pathJSONFile);
UsersPajo[] usersPajos2= null;
try {
usersPajos2 = objectMapper.readValue(jsonFile, UsersPajo[].class);
System.out.println("_usersPajos2___" + usersPajos2);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return Arrays.toString(usersPajos2);
}

Getting empty JSON using Jackson [duplicate]

This question already exists:
How to use Jackson Serializer when you don't know the property names [duplicate]
Closed 4 years ago.
Right now I'm trying to parse incoming JSON that is in this format:
{
<email>: {
<name>: <string>, # setting value
...
},
...
}
For example:
{
"aaa#example.com": {
"statement": true
},
"bbb#example.com": {
"statement": false
}
}
I also will not know how many emails will be in this JSON. I am a little befuddled as to how you could get all these emails with Jackson without knowing the property name for this, and I was wondering if it was possible.
Here is my code so far:
public class GDPRConsent extends Model {
#JsonIgnore
private static final String GDPR_CONSENT = "gdprConsent";
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonProperty
private ArrayList<String> emails;
#JsonProperty("serviceDataCollection")
private String dataCollection;
#JsonProperty("serviceDataCollection")
public String getDataCollectionConsent() {
return dataCollection;
}
#JsonProperty
public ArrayList<String> getEmails() {
return emails;
}
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
#Override
public String getId() {
return GDPR_CONSENT;
}
}
Here is my parser:
public static <T> T parseObject(String sourceJson, Class<T> classToParse) {
T parsedObject = null;
try {
parsedObject = sObjectMapper.readValue(sourceJson, classToParse);
} catch (JsonParseException e) {
LogUtils.d(LOG_TAG, "parseObject JsonParseException: " + e.toString());
} catch (JsonMappingException e) {
LogUtils.d(LOG_TAG, "parseObject JsonMappingException: " + e.toString());
} catch (IOException e) {
LogUtils.d(LOG_TAG, "parseObject IOException: " + e.toString());
}
return parsedObject;
}
I am currently getting an empty result returned even though I know the JSON is being passed in.
If your JSON only includes the data given in your example, then it corresponds to a TypeReference<Map<String, Map<String, Boolean>>>, which is basically a mapping of strings to a mapping of strings to booleans. An example parser looks like this (no extra POJOs required):
import java.io.IOException;
import java.util.Map;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSONParser {
static final String TEST_JSON = "{"
+" \"aaa#example.com\": {"
+" \"statement\": true"
+"},"
+"\"bbb#example.com\": {"
+" \"statement\": false"
+"}"
+"}";
public static void main (String... args) {
ObjectMapper mapper = new ObjectMapper();
try {
Map<String, Map<String, Boolean>> jsonAsNestedMap = mapper.readValue(
TEST_JSON, new TypeReference<Map<String, Map<String, Boolean>>>() {
});
System.out.println(jsonAsNestedMap);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
This will print out
{aaa#example.com={statement=true}, bbb#example.com={statement=false}}
If the innermost values of your JSON are more complex, then you can use TypeReference<Map<String, Map<String, Object>>>:
static final String TEST_JSON = "{"
+" \"aaa#example.com\": {"
+" \"statement\": true,"
+" \"another_property\" : \"value 1\""
+"},"
+"\"bbb#example.com\": {"
+" \"statement\": false,"
+" \"another_property\" : \"value 2\""
+"}"
+"}";
//...
public static void main (String... args) {
//...
Map<String, Map<String, Object>> jsonAsNestedMap = mapper.readValue(
TEST_JSON, new TypeReference<Map<String, Map<String, Object>>>() {
});
//...
}
Accessing individual properties is possible through normal map iteration and accessor methods:
for (Entry<String, Map<String, Object>> e : jsonAsNestedMap.entrySet()) {
System.out.println("email:" + e.getKey() + ", another_property: "
+ e.getValue().get("another_property"));
}
which would give
email:aaa#example.com, another_property: value 1
email:bbb#example.com, another_property: value 2
I'm trying to parse incoming JSON that is in this format
As already explained in your duplicate question, you can parse into a Map.
public class EmailData {
private boolean statement;
public boolean isStatement() {
return this.statement;
}
public void setStatement(boolean statement) {
this.statement = statement;
}
#Override
public String toString() {
return "EmailData[statement=" + this.statement + "]";
}
}
Test
String json = "{" +
"\"aaa#example.com\": {" +
"\"statement\": true" +
"}," +
"\"bbb#example.com\": {" +
"\"statement\": false" +
"}" +
"}";
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, EmailData>> typeRef = new TypeReference<>() {/**/};
HashMap<String, EmailData> emails = mapper.readValue(json, typeRef);
System.out.println(emails);
Output
{aaa#example.com=EmailData[statement=true], bbb#example.com=EmailData[statement=false]}
If you prefer the #JsonAnySetter approach, you can do something like this:
public class Content {
private List<EmailData> emailData = new ArrayList<>();
#JsonAnySetter
public void addEmail(String name, EmailData value) {
value.setEmail(name);
this.emailData.add(value);
}
#Override
public String toString() {
return this.emailData.toString();
}
}
public class EmailData {
private String email;
private boolean statement;
#JsonIgnore
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isStatement() {
return this.statement;
}
public void setStatement(boolean statement) {
this.statement = statement;
}
#Override
public String toString() {
return "EmailData[email=" + this.email + ", statement=" + this.statement + "]";
}
}
Test
String json = "{" +
"\"aaa#example.com\": {" +
"\"statement\": true" +
"}," +
"\"bbb#example.com\": {" +
"\"statement\": false" +
"}" +
"}";
ObjectMapper mapper = new ObjectMapper();
Content content = mapper.readValue(json, Content.class);
System.out.println(content);
Output
[EmailData[email=aaa#example.com, statement=true], EmailData[email=bbb#example.com, statement=false]]

Data parse from JSON Response

I can't parse data from Response:
here is my snippet:
Response = '{"sys":"[{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Mathbaria Upazila\"},{\"division\":\"Barisal\",\"district\":\"Jhalokati Zila\",\"upazilla\":\"Rajapur Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barguna Zila\",\"upazilla\":\"Amtali Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Banari Para Upazila\"},{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Pirojpur Sadar Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Muladi Upazila\"}]"}';
JSONObject json = new JSONObject(response);
JSONArray userdetails = json.getJSONArray("sys");
for (int i=0; i<userdetails.length(); i++) {
JSONObject user = userdetails.getJSONObject(i);
String division = user.getString("division");
String district = user.getString("district");
String upazilla = user.getString("upazilla");
}
I debug the code. Code stop when tried to check userdetails length.
Any ideas ?
There should be no " in front of [{ nor after }]
This should work:
String response = "{\"sys\":[{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Mathbaria Upazila\"},{\"division\":\"Barisal\",\"district\":\"Jhalokati Zila\",\"upazilla\":\"Rajapur Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barguna Zila\",\"upazilla\":\"Amtali Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Banari Para Upazila\"},{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Pirojpur Sadar Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Muladi Upazila\"}]}";
JSONObject json = new JSONObject(response);
JSONArray userdetails = json.getJSONArray("sys");
for (int i=0; i<userdetails.length(); i++)
{
JSONObject user = userdetails.getJSONObject(i);
String division = user.getString("division");
String district = user.getString("district");
String upazilla = user.getString("upazilla");
}
Sample code :
String JSON_DATA =
"{"
+ " \"geodata\": ["
+ " {"
+ " \"id\": \"1\","
+ " \"name\": \"Julie Sherman\","
+ " \"gender\" : \"female\","
+ " \"latitude\" : \"37.33774833333334\","
+ " \"longitude\" : \"-121.88670166666667\""
+ " },"
+ " {"
+ " \"id\": \"2\","
+ " \"name\": \"Johnny Depp\","
+ " \"gender\" : \"male\","
+ " \"latitude\" : \"37.336453\","
+ " \"longitude\" : \"-121.884985\""
+ " }"
+ " ]"
+ "}";
JSONObject json;
JSONArray geodetails = null;
JSONObject user;
try {
json = new JSONObject(JSON_DATA);
geodetails = json.getJSONArray("geodata");
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < geodetails.length(); i++) {
try {
user = geodetails.getJSONObject(i);
String name = user.getString("name");
String gender = user.getString("gender");
String latitude = user.getString("latitude");
Log.d("Json response", " " + name+" "+gender+" "+latitude);
} catch (JSONException e) {
e.printStackTrace();
}
}
Try below format. i.e:
String response = "{\"sys\":[{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Mathbaria Upazila\"},{\"division\":\"Barisal\",\"district\":\"Jhalokati Zila\",\"upazilla\":\"Rajapur Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barguna Zila\",\"upazilla\":\"Amtali Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Banari Para Upazila\"},{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Pirojpur Sadar Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Muladi Upazila\"}]}";
And test JSON format here without "\"
& Your code of json parsing is right
Your Json response is not correct. There should not be any codes before JsonArray, response should be like this
{"sys":[{"division":"Barisal","district":"Pirojpur Zila","upazilla":"Mathbaria Upazila"},{"division":"Barisal","district":"Jhalokati Zila","upazilla":"Rajapur Upazila"},{"division":"Barisal","district":"Barguna Zila","upazilla":"Amtali Upazila"},{"division":"Barisal","district":"Barisal Zila","upazilla":"Banari Para Upazila"},{"division":"Barisal","district":"Pirojpur Zila","upazilla":"Pirojpur Sadar Upazila"},{"division":"Barisal","district":"Barisal Zila","upazilla":"Muladi Upazila"}]}
Your json object is:
{
"sys": [{
"division": "Barisal",
"district": "Pirojpur Zila",
"upazilla": "Mathbaria Upazila"
}, {
"division": "Barisal",
"district": "Jhalokati Zila",
"upazilla": "Rajapur Upazila"
}, {
"division": "Barisal",
"district": "Barguna Zila",
"upazilla": "Amtali Upazila"
}, {
"division": "Barisal",
"district": "Barisal Zila",
"upazilla": "Banari Para Upazila"
}, {
"division": "Barisal",
"district": "Pirojpur Zila",
"upazilla": "Pirojpur Sadar Upazila"
}, {
"division": "Barisal",
"district": "Barisal Zila",
"upazilla": "Muladi Upazila"
}]
}
For automatic serialization and deserialization use Gson library. This can be done in Gson in a very simple manner. Go to jsonschematopojo.org and covert your json to pojo classes. the resultant pojo class for your json object is:
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class YourJsonClass {
#SerializedName("sys")
#Expose
private List<Sy> sys = null;
public List<Sy> getSys() {
return sys;
}
public void setSys(List<Sy> sys) {
this.sys = sys;
}
public class Sy {
#SerializedName("division")
#Expose
private String division;
#SerializedName("district")
#Expose
private String district;
#SerializedName("upazilla")
#Expose
private String upazilla;
public String getDivision() {
return division;
}
public void setDivision(String division) {
this.division = division;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getUpazilla() {
return upazilla;
}
public void setUpazilla(String upazilla) {
this.upazilla = upazilla;
}
}
Now to access it, that's got simpler now,
String response = "{\"sys\":[{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Mathbaria Upazila\"},{\"division\":\"Barisal\",\"district\":\"Jhalokati Zila\",\"upazilla\":\"Rajapur Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barguna Zila\",\"upazilla\":\"Amtali Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Banari Para Upazila\"},{\"division\":\"Barisal\",\"district\":\"Pirojpur Zila\",\"upazilla\":\"Pirojpur Sadar Upazila\"},{\"division\":\"Barisal\",\"district\":\"Barisal Zila\",\"upazilla\":\"Muladi Upazila\"}]}";
Gson g1 = new Gson();
YourJsonClass response2 = g1.fromJson(response, YourJsonClass.class);
Now, you need to iterate the response2 object as per your convenience.
for(int i=0; i < response2.getSys().size(); i++) {
System.out.println(response2.getSys().get(i).getDivision());
System.out.println(response2.getSys().get(i).getDistrict());
System.out.println(response2.getSys().get(i).getUpazilla());
}

Json to Java Mapping

I want to map below Json data to java object of List<Map<String, String>> type.
Sample Json:
{
{
a:b,
c:d
},
{
e:f,
g:h,
i:j
},
{
h:k
}
}
Here a:b represents key-value pair. So a:b and c:d will be mapped to first map of the list and so on.
one way to do this is by building JSON tree and access each node and store the pair into the map.
Is there a better way to do this (cleaner approach)?
Here is the code to read a List<Map<String, String>> using the Jackson library, with your example data as input:
public class JsonTest {
public static void main(String[] args) throws Exception {
final String json
= "[\n"
+ " {\n"
+ " \"a\":\"b\",\n"
+ " \"c\":\"d\"\n"
+ " },\n"
+ " {\n"
+ " \"e\":\"f\",\n"
+ " \"g\":\"h\",\n"
+ " \"i\":\"j\"\n"
+ " },\n"
+ " {\n"
+ " \"h\":\"k\"\n"
+ " }\n"
+ "]"; // [{a:b,c:d},{e:f,g:h,i:j},{h:k}]
ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = TypeFactory.defaultInstance();
List<Map<String, String>> list = mapper.readValue(json,factory
.constructCollectionType(List.class, factory
.constructMapType(Map.class, String.class, String.class)));
System.out.println(list.toString());
}
}
Note: I had to fix your outermost braces from {} to [], which is the correct JSON list syntax.
You can use Jackson to achieve this task through below example code
public class JacksonExample {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
// Convert JSON string from file to Object
User user = mapper.readValue(new File("C:\\user.json"), User.class);
System.out.println(user);
// Convert JSON string to Object
String jsonInString = "{\"age\":33,\"messages\":[\"msg 1\",\"msg 2\"],\"name\":\"xyz\"}";
User user1 = mapper.readValue(jsonInString, User.class);
System.out.println(user1);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
First I made few changes to your json to make it valid
{
"key":
[{
"a": "b",
"c": "d"
},
{
"e": "f",
"g": "h",
"i": "j"
},
{
"h": "k"
}]
}
Please find the below code that I have tried out :
ObjectMapper mapper = new ObjectMapper();
ObjectNode objectNode1 = mapper.createObjectNode();
Map<String, Object> i = mapper.readValue(new File("J:/temp/sample.json"), Map.class);
System.out.println(i.get("key"));
System.out.println(i.values());
Output :
//For System.out.println(i.get("key"));
[{a=b, c=d}, {e=f, g=h, i=j}, {h=k}]
//For System.out.println(i.values());
[[{a=b, c=d}, {e=f, g=h, i=j}, {h=k}]]
If the above approach helps you, Make a right decision based on your needs either i.get("key") or i.values()
Just use gson library to Json to object and object to Json
import java.lang.reflect.Type;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
Object to Json
Gson gson = new Gson();
Student obj=new Student();
String jsonInString = gson.toJson(obj);
Json To Object
Student obj = gson.fromJson(jsonInString, Student.class);

Parse List of JSON objects using GSON

I have a JSON object like this:
{
"user1": {
"timeSpent": "20.533333333333335h",
"worklog": [
{
"date": "06/26/2013",
"issues": [
{
"issueCode": "COC-2",
"comment": "\ncccccc",
"timeSpent": "20.533333333333335h"
}
],
"dayTotal": "20.533333333333335h"
}
]
},
"admin": {
"timeSpent": "601.1h",
"worklog": [
{
"date": "06/25/2013",
"issues": [
{
"issueCode": "COC-1",
"comment": "",
"timeSpent": "113.1h"
}
],
"dayTotal": "113.1h"
},
{
"date": "06/26/2013",
"issues": [
{
"issueCode": "COC-1",
"comment": "",
"timeSpent": "8h"
},
{
"issueCode": "COC-2",
"comment": "",
"timeSpent": "480h"
}
],
"dayTotal": "488h"
}
]
}
}
and trying to parse it with Gson:
Gson gson = new Gson();
Book responseBean = gson.fromJson(jsonString, Book.class);
But the 'responceBean' is always 'null'
Here are all the other classes:
public class Book {
private List<User> user = new LinkedList<User>();
public List<User> getUser() {
return user;
}
public void setUser(List<User> user) {
this.user = user;
}
}
public class User {
private String timeSpent;
private List<WorkLog> worklogs = new LinkedList<WorkLog>();;
public List<WorkLog> getWorklogs() {
return worklogs;
}
public void setWorklogs(List<WorkLog> worklogs) {
this.worklogs = worklogs;
}
public String getTimeSpent() {
return timeSpent;
}
public void setTimeSpent(String timeSpent) {
this.timeSpent = timeSpent;
}
}
public class WorkLog{
private String date;
private String dayTotal;
private List<Issues> issues;
public String getDate(){
return this.date;
}
public void setDate(String date){
this.date = date;
}
public String getDayTotal(){
return this.dayTotal;
}
public void setDayTotal(String dayTotal){
this.dayTotal = dayTotal;
}
public List<Issues> getIssues(){
return this.issues;
}
public void setIssues(List<Issues> issues){
this.issues = issues;
}
}
public class Issues{
private String comment;
private String issueCode;
private String timeSpent;
public String getComment(){
return this.comment;
}
public void setComment(String comment){
this.comment = comment;
}
public String getIssueCode(){
return this.issueCode;
}
public void setIssueCode(String issueCode){
this.issueCode = issueCode;
}
public String getTimeSpent(){
return this.timeSpent;
}
public void setTimeSpent(String timeSpent){
this.timeSpent = timeSpent;
}
}
This is my latest attempt. Somehow I cannot figure out the right way. Will be very appreciative for any help.
Your JSON model does not match your object model.
You need an intermediate layer to fill the gap: a TypeAdapter.
Moreover there is no naming information for the user.
And finally there is a name mismatch: "worklog" in JSON, "worklogs" in Java.
Here is a fixed version:
Java model:
class User {
private String timeSpent;
#SerializedName("worklog")
private List<WorkLog> worklogs = new LinkedList<WorkLog>();
private String name;
public List<WorkLog> getWorklogs() {
return worklogs;
}
public void setWorklog(List<WorkLog> worklogs) {
this.worklogs = worklogs;
}
public String getTimeSpent() {
return timeSpent;
}
public void setTimeSpent(String timeSpent) {
this.timeSpent = timeSpent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The plumbing to fill the gap:
class BookTypeAdapter implements JsonSerializer<Book>, JsonDeserializer<Book>
{
Gson gson = new Gson();
public JsonElement serialize(Book book, Type typeOfT, JsonSerializationContext context)
{
JsonObject json = new JsonObject();
for (User user : book.getUser())
{
json.addProperty(user.getName(), gson.toJson(user));
}
return json;
}
public Book deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
JsonObject json = element.getAsJsonObject();
Book book = new Book();
for (Entry<String, JsonElement> entry : json.entrySet())
{
String name = entry.getKey();
User user = gson.fromJson(entry.getValue(), User.class);
user.setName(name);
book.getUser().add(user);
}
return book;
}
}
And a roundtrip:
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Book.class, new BookTypeAdapter());
Gson gson = builder.create();
Book book = gson.fromJson("{" +
" \"user1\": {" +
" \"timeSpent\": \"20.533333333333335h\"," +
" \"worklog\": [" +
" {" +
" \"date\": \"06/26/2013\"," +
" \"issues\": [" +
" {" +
" \"issueCode\": \"COC-2\"," +
" \"comment\": \"\ncccccc\"," +
" \"timeSpent\": \"20.533333333333335h\"" +
" }" +
" ]," +
" \"dayTotal\": \"20.533333333333335h\"" +
" }" +
" ]" +
" }," +
" \"admin\": {" +
" \"timeSpent\": \"601.1h\"," +
" \"worklog\": [" +
" {" +
" \"date\": \"06/25/2013\"," +
" \"issues\": [" +
" {" +
" \"issueCode\": \"COC-1\"," +
" \"comment\": \"\"," +
" \"timeSpent\": \"113.1h\"" +
" }" +
" ]," +
" \"dayTotal\": \"113.1h\"" +
" }," +
" {" +
" \"date\": \"06/26/2013\"," +
" \"issues\": [" +
" {" +
" \"issueCode\": \"COC-1\"," +
" \"comment\": \"\"," +
" \"timeSpent\": \"8h\"" +
" }," +
" {" +
" \"issueCode\": \"COC-2\"," +
" \"comment\": \"\"," +
" \"timeSpent\": \"480h\"" +
" }" +
" ]," +
" \"dayTotal\": \"488h\"" +
" }" +
" ]" +
" }" +
"}", Book.class);
String json = gson.toJson(book);
Have a look at my tutorial to get an idea of what is possible with Gson: Java/JSON mapping with Gson
Enjoy! :)
I had some problem before a month. As far as I remember it was because, same as you, I forgot to make "new" to objects. I mean that it should look:
public class User {
private String timeSpent;
private List<WorkLog> worklogs = new List < WorkLog >();
}
Try this and I hope that it will help.
P.S.
Also as Erik Pragt said you have array of Users, not just single one. So you will have to make 1 more class that contains a List < Users >.

Categories

Resources