I have a JSON file with multiple entries that have same attribute names, but different attribute values, such as:
{
"name" : { "first" : "A", "last" : "B" },
"gender" : "MALE",
"married" : false,
"noOfChildren" : 2
},
{
"name" : { "first" : "C", "last" : "D" },
"gender" : "FEMALE",
"married" : true,
"noOfChildren" : 1
}
The class that it should be mapped is:
public class Human {
private Name name;
private String gender;
private int age;
<getter, setters etc>
}
EDIT:
Service code is :
List<Human> humans = null;
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
humans= objectMapper.readValue(json, new TypeReference<List<Human>>(){});
} catch (IOException e) {
e.printStackTrace();
}
JSON is parsed from HTTP entity and with correct format and now I added the annotation ass suggested in the answers.
As you can see, they have some attributes in common, but differ in others, and I would like to map those common fields. Is it possible to map the JSON this way ? I have tried mapping JSON to a collection/list/array of JsonNodes, but I keep getting erros about deserialization, while mapping only one instance of JSON entry works just fine. Is there another way of doing this ?
Use
#JsonIgnoreProperties(ignoreUnknown = true)
public class Human {
private Name name;
private String gender;
// getters, settets, default constructor
}
Or if you are using Lombok then it will be
#Data
#NoArgsConstructor
#JsonIgnoreProperties(ignoreUnknown = true)
public class Human {
private Name name;
private String gender;
}
use
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
while deserializing json to POJO class.
The JSON you have provide in question will give following error, as it is not a valid one.
Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
Valid Json would be like this:
[
{
"name": {
"first": "A",
"last": "B"
},
"gender": "MALE",
"married": false,
"noOfChildren": 2
},
{
"name": {
"first": "C",
"last": "D"
},
"gender": "FEMALE",
"married": true,
"noOfChildren": 1
}
]
Related
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;
}
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)
I have a json like below
{
"department": [
{
"status": "active",
"count": "100"
},
{
"status": "active",
"count": "300"
}
],
"finance": [
{
"status": "inactive",
"count": "500"
},
{
"status": "active",
"count": "450"
}
]
}
My Object is like below
class CurrentInfo
{
private String status;
private int count;
//getters and setters
}
I wanted to convert this JSON to a Map<String,List<CurrentInfo>>. I can convert the individual nodes using the below
ObjectMapper mapper = new ObjectMapper();
CurrentInfo currentinfo = mapper.readValue(jsonString, CurrentInfo.class);
Is there a way I can convert the previously mentioned JSON directly into a Map<String,List<CurrentInfo>>
Yes you can, and according to JSON above count is String type not int
class CurrentInfo {
private String status;
private String count;
//getters and setters
}
The use TypeReference to convert json string to java object
Map<String, List<CurrentInfo>> currentInfo = mapper.readValue(
jsonString,
new TypeReference<Map<String, List<CurrentInfo>>>() {});
I need to convert below json to java object of #RequestBody.
{
"entity": {
"id": 3,
"name": "james"
},
"conjunction": "OR",
"conditions": [
{
"operation": "equalTo",
"dataKey": "department",
"dataType": "string",
"value": "abc"
},
{
"operation": "notEqualTo",
"dataKey": "ID",
"dataType": "number",
"value": "100"
},
{
"operation": "notEqualTo",
"dataKey": "name",
"dataType": "strubg",
"value": "jack"
},
{
"operation": "between",
"dataKey": "END_DATE",
"dataType": "date",
"value1": "20180502",
"value2": "20180519"
}
]
}
The first three element in the array correspond to below java object.
public class ComparisonCondition extends Condition {
private String value;
}
The last element correspond below object.
public class BetweenCondition extends Condition {
private String value1;
private String value2;
}
They all inherit from below object.
public class Condition {
private String dataKey;
private String dataType;
private String operation;
}
The spring mvc method is below.
#RequestMapping(value = RequestAction.FILTER, method = RequestMethod.POST)
public List<Student> filter(
#RequestBody Filter<Student> filterConfig) {
return null;
}
The Filter object is below.
public class Filter<T> {
private String conjunction;
private T entity;
private List<Condition> conditions;
}
How can I map the json to java object successfully?
Currently it report "Could not read JSON: Unrecognized field "value" (class com.ssc.rest.entity.Condition), not marked as ignorable (3 known properties: "dataType", "dataKey", "operation"])
For your error, if the jackson parser don't know a field, it throws an exception.
You can avoid it by putting the annotation :
#JsonIgnore(ignoreUnknown=true)
on the target object.
For your mapping, I recommand to you to create an object corresponding to your json input, and then do manually your mapping to your target objects.
You are passing 4 variables in JSON for COndition
{
"operation": "equalTo",
"dataKey": "department",
"dataType": "string",
"value": "abc"
},
but your Java POJO has only 3 variables
public class Condition {
private String dataKey;
private String dataType;
private String operation;
}
just add value as well it will work fine.
Bottom line is : POJO class should have all the fields passed in JSON.
By the way your exception is telling same thing
Unrecognized field "value"
Edit 1:
I missed BetweenCondition and ComparisonCondition
You can define the Base Class in your case Condition with Sub Class property and hopefully it should work
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "javaclass")
#JsonSubTypes({
#Type(value = ComparisonCondition.class),
#Type(value = BetweenCondition.class)
})
public class Condition {
private String dataKey;
private String dataType;
private String operation;
}
Assuming I have a JSON response like this:
[{
"employees" : [{
"name" : "Peter",
"dob" : "19850101"
}, {
"name" : "Mark",
"dob" : "19850202"
}, {
"name" : "Steve",
"dob" : "19850303"
}
],
"projects" : [{
"reference" : "P1",
"name" : "Project One",
}, {
"reference" : "P2",
"name" : "Project Two",
}, {
"reference" : "P3",
"name" : "Project Three",
}
],
"projectMembers" : [{
"project" : {
"reference" : "P1"
},
"employees" : [{
"name" : "Peter",
"dob" : "19850101"
}, {
"name" : "Steve",
"dob" : "19850303"
}
]
}, {
"project" : {
"reference" : "P2"
},
"employees" : [{
"name" : "Peter",
"dob" : "19850101"
}, {
"name" : "Mark",
"dob" : "19850101"
}, {
"name" : "Steve",
"dob" : "19850303"
}
]
},
]
}
]
How do I parse this JSON with Jackson. What is the most relevant java object to create for using the Jackson ObjectMapper? Or this should be handled using any custom deserializer?
In my Opinion you will need two basic DTOs. One for the elements refering to the Projects, which will have two fields (reference and name, both as Strings) and one for the Employees, which will also have two fields (name (String) and dob (Long)). Then you will need an extra Class to handle the combination of a Project to multiple employees (this class has two fields: one Project and a List of Employees). To be able to parse the JSON you will then have to create a DTO wrapping your JSON. This Class will have three fields one list of employees, one list of projects and one list of the class assigning employees to projects.
For example something like this:
public class Employee{
private String name;
private Long dob;
//default constructor and getter/setter
}
public class Project{
private String reference;
private String name;
//default constructor and getter/setter
}
public class EmployeesToProject{
private Project project;
private List<Employee>;
//default constructor and getter/setter
}
public class CompleteJSON{
private List<Employee> employees;
private List<Project> projects;
private List<EmployeesToProject> projectMembers;
//default constructor and getter/setter
}
You can then parse your JSON with the CompleteJSON-Class
You should rename the DTOs to something more readable