Unable Parse a JSON using Jackson - java

I have a mongo database call in my code. The response from the database is mapped using codehaus jackson.
Json:
[
{
"_id": "555",
"rates": 1,
"reviews": [
{
"author_name": "Instructor 9999",
"_authKey": "demo\\556",
"text": "asdfa",
"date": 551,
"_id": "5454-4920",
"title": "asdf",
"comments": []
}
],
"votedUsers": [
{
"mng\\39999": 4
}
],
"rating": 4
},
{
"_id": "45589",
"rates": 1,
"reviews": [
{
"author_name": "feef",
"_authKey": "ad\\ads",
"text": "Working perfect",
"date": 1498659163,
"_id": "asdas-319",
"title": "test",
"comments": []
}
],
"votedUsers": [
{
"abc\\bis#cdf.com": 4
}
],
"rating": 4
}
]
I have created the below DTO Stucture:
#JsonIgnoreProperties(ignoreUnknown = true)
public class MaterialReviewsDTO implements Serializable {
private static final long serialVersionUID = 1L;
private String _id;
private int rates;
private List<ReviewsDTO> reviews;
private List<VotedUsersDTO> votedUsers;
//List<TypeReference<HashMap<String, String>>> votedUsers;
private int rating;.
//Getter Setter
}
#JsonIgnoreProperties(ignoreUnknown = true)
public class VotedUsersDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Map<String, String> votedUser;
//Getter Setter
}
Below is the code where I am firing the query:
List<MaterialReviewsDTO> materialReviewsDTOs = DBConnectionRealmByDBName
.find(query,
MaterialReviewsDTO.class,
CollectionNameConstant.REVIEWS_COLLECTION);
Problem is all the JSON is getting mapped in DTO except the below part:
"votedUsers" : [
{
"abc\\bis#cdf.com" : 4
}
]
VotedUserDTO is null in response. VotedUsers is a list of object containg data in key-value pair.
I am not mentioning ReviewsDTO as this is getting mapped perfectly. How can I map votedUsers part?
Note: I am using Spring for development.

Some of the observations from your JSON
1. Json should be designed with Fixed key and variable values in mind.
2. Since in above case both Key and values are variable, we can use Map
So final solution is
change from private List<VotedUsersDTO> votedUsers; to private List<Map<String, Integer>> votedUsers

private List<Map<String, String>> votedUsers;
Do not use the explicit votedUser DTO.

The votedUsers is expected to be a List of VotedUsersDTOs.
If you look at your VotedUsersDTO in the JSON:
{
"abc\\bis#cdf.com" : 4
}
This would imply there is a field abc\\bis#cdf.com where you want the value to be 4.
This doesn't comply with id or votedUser Map in the DTO definition.

Related

Deserializing complex json with matching objects by id (Jackson)

I have a proprietary API that return a complex JSON like:
{
"store": "store_name",
"address": "store_address",
"department": [
{
"name": "d1",
"type": "t1",
"items": [
"i1",
"i2"
]
},
{
"name": "d2",
"type": "t2",
"items": [
"i3"
]
}
],
"itemDescriptions": [
{
"id": "i1",
"description": "desc1"
},
{
"id": "i2",
"description": "desc2",
"innerItems": [
"i2"
]
},
{
"id": "i3",
"description": "desc3"
}
]
}
Is it possible to deserialize this JSON using Jackson into:
#AllArgsConstructor
class Store {
private final String store;
private final String address;
private final List<Department> departments;
/*some logic*/
}
#AllArgsConstructor
class Department {
private final String name;
private final String type;
private final List<Item> items;
/*some logic*/
}
#AllArgsConstructor
class Item {
private final String id;
private final String description;
private final List<Item> innerItems;
/*some logic*/
}
I tried to find answers, but find only this question without solution.
I know that I can do it in my code (deserialize as it is and create objects from result), but its very memory intensive (I have a lot of json and it can be large).
I know that I can write fully custom deserializer, but in this case, I have to describe the deserialization of each field myself - in case of some changes, I will have to change the deserializer, and not just the class(POJO/DTO).
Is there a way to do this with Jackson (or Gson) or with a minimal (preferably relatively generic) amount of my code?

Parse a json list into list of object Java

I have a response as follows
[
{
"segmentId": "Source_2021-09-01_2021-10-01",
"columns": [
"merchantRefNum",
"customerId",
"firstName",
],
"events": [
{
"merchantRefNum": "67456456",
"customerId": rfgvkhbj,
"firstName": "peter",
},
{
"merchantRefNum": "654584856",
"customerId": null,
"firstName": "peter"
}
]
}
]
I want to map this json to a POJO object and have created this class
public class MyClass {
private String segmentId;
private List<String> columns;
private List<KeyValuePair> events;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
#JsonIgnoreProperties(ignoreUnknown = true)
public static class KeyValuePair {
Map<String, String> event;
}
}
I am currently using this way to read this
List<MyClass> responses = new ObjectMapper().readValue(jsonString,new TypeReference<List<MyClass>>(){});
The size of events is 2 but each event is coming as null instead of a map.
Can Someone please help me ?
To achieve your goal you have to adjust your JSON as follows:
[
{
"segmentId":"Source_2021-09-01_2021-10-01",
"columns":[
"merchantRefNum",
"customerId",
"firstName"
],
"events":[
{
"event":{
"merchantRefNum":"67456456",
"customerId":"rfgvkhbj",
"firstName":"peter"
}
},
{
"event":{
"merchantRefNum":"654584856",
"customerId":null,
"firstName":"peter"
}
}
]
}
]
Notice the event fields that have been added.
Or, change your DTO, like this:
class MyClass {
private String segmentId;
private List<String> columns;
private List<Map<String, String>> events;
}

Error parsing JSON (MismatchedInputException)

I'm having problems parsing JSON, this is the error:
out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList<packagename....>` out of START_OBJECT token
And I know why it is happening I just don't know how to fix it. This JSON works:
{
"status_code": "SUCCESS",
"time": {
"date": "Mar 23, 2021 1:14:39 AM"
},
"info": [
{
"person": "2.2",
"role": "TEACHER"
},
{
"person": "2.3",
"role": "TEACHER"
}
]
}
This one does not:
{
"status_code": "SUCCESS",
"time": {
"date": "Mar 23, 2021 3:49:27 AM"
},
"info": {
"id": "1",
"person": [
{
"identifier": "John",
"role": "TEACHER"
},
{
"identifier": "Homer",
"role": "TEACHER"
},
{
"identifier": "Michael",
"role": "TEACHER"
},
{
"identifier": "Sarah",
"role": "TEACHER"
}
]
}
}
The problem seems to be the { character in front of the info field because with [ works. So this is the method I'm using to parse the JSON:
public Mono<PersonResponse> searchById(String id) {
return webClient.get().uri(id).retrieve().bodyToMono(PersonResponse.class);
}
Also tried:
public Mono<PersonResponse[]> searchById(String id) {
return webClient.get().uri(id).retrieve().bodyToMono(PersonResponse[].class);
}
Error right on line: 1, column: 1. Any suggestions of how to implement the method?
EDIT: Added classes.
PersonResponse:
public class PersonResponse implements Serializable{
private static final long serialVersionUID = 7506229887182440471L;
public String status_code;
public Timestamp time;
public List<PersonDetails> info;
public PersonResponse() {}
...getters / setters / toSting
PersonDetails:
public class PersonDetails implements Serializable{
private static final long serialVersionUID = 1294417456651475410L;
private int id;
private List<Person> person;
public PersonDetails(int version) {
super();
this.version = version;
}
...getters / setters / toSting
Person
public class Person implements Serializable{
private static final long serialVersionUID = 3290753964441709903L;
private String identifier;
private String role;
public Person(String identifier, String role) {
super();
this.identifier = identifier;
this.role = role;
}
...getters / setters / toSting
The problem isn't the JSON necessarily, it's that the JSON structure doesn't match your PersonResponse class. There's an info variable in PersonResponse that requires an array of what I assume to be persons, in the second example you're trying to push an object in there, which you can't. You have to either change your JSON, which you don't seem to want in this case, or the class you're trying to parse it to.
You need to restructure the info variable in PersonResponse to match the object you're trying to parse to it.

Gson: skip node level for serialization

I have some json which contains fields with custom names, e.g.:
{
"user_id": 123,
"user_name": "John",
"field_with_custom_name_1": "value1",
"field_with_custom_name_2": "value2",
"field_with_custom_name_3": "value3"
}
For describe this json the next model was created:
public class UserData {
#SerializedName("user_id")
private int userId;
#SerializedName("user_name")
private String userName;
private Map<String, String> customFields;
}
But after serialization we have json with the next structure:
{
"user_id": 123,
"user_name": "John",
"customFields": {
"field_with_custom_name_1": "value1",
"field_with_custom_name_2": "value2",
"field_with_custom_name_3": "value3"
}
}
Can you suggest how to ignore "customFields" level in the result?
You can use the following annotation to exclude a field from serialization and deserialization:
#Expose (serialize = false, deserialize = false)

serialize json to pojo class

I have a JSON response coming as shown below. I am trying to make a POJO for this so that I can serialize this JSON into my POJO.
{
"holder": [
{
"ids": [
{
"data": "abcdef1234",
"time": 1452720139465,
"days": 16813
},
{
"data": "abcdef12345678",
"time": 1452720139465,
"days": 16813
},
{
"data": "abcdef12345678901234",
"time": 1452720139465,
"days": 16813
}
],
"type": "HELLO"
}
]
}
And this is my POJO I was able to come up with but it doesn't look right.
public class TestResponse {
private List<Ids> holder;
private String type;
// getters and setters
public static class Ids {
private String data;
private long time;
private long days;
// getters and setters
}
}
My json is not getting serialized to my above POJO
go to this link www.jsonschema2pojo.org and past yout json and extract jar files and import in your project and do some changes link this.
$class TestResponse {
to
class TestResponse implement serializable{

Categories