Reputation: 43
I want to convert a json (shown below) into a java object. I have created java classes for the json objects without using any jackson annotations for now.
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestJunkie {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static void main(String[] args) throws Exception {
String json = "{\r\n" +
" \"Info\":{\r\n" +
" \"prop1\": \"value1\",\r\n" +
" \"prop2\": \"value2\",\r\n" +
" \"prop3\": \"value3\"\r\n" +
" },\r\n" +
" \"Data\":{\r\n" +
" \"prop1\": \"value1\",\r\n" +
" \"prop2\": \"value2\"\r\n" +
" }\r\n" +
"}";
Pack pack = objectMapper.readValue(json, Pack.class);
System.out.println(pack);
}
}
I converted the above Json object into a Java class called "Pack" below:
import org.apache.commons.lang3.builder.ToStringBuilder;
public class Pack {
private Info info;
private Data data;
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
@Override
public String toString() {
return new ToStringBuilder(this).append("info", info).append("data", data).toString();
}
}
I have deliberately omitted the classes for Info and Data. Their variables, getters, setters match the json. I can include them if you want.
I get the following exception. Why does this exception occur & how do I fix it ?
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Info" (class com.tester.Jacksons.Pack), not marked as ignorable (2 known properties: "data", "info"])
at [Source: (String)"{
"Info":{
"prop1": "value1",
"prop2": "value2",
"prop3": "value3"
},
"Data":{
"prop1": "value1",
"prop2": "value2"
}
}"; line: 2, column: 10] (through reference chain: com.tester.Jacksons.Pack["Info"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:60)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:822)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1152)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1582)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1560)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
at com.tester.Jacksons.TestJunkie.main(TestJunkie.java:22)
Upvotes: 2
Views: 4248
Reputation: 7546
Your properties inside Pack are not matching the names because in json it's starting with capital case letter.
Hence, update Pack
as follows:
import org.apache.commons.lang3.builder.ToStringBuilder;
public class Pack {
@JsonProperty("Info")
private Info info;
@JsonProperty("Data")
private Data data;
public Info getInfo() {
return info;
}
public void setInfo(Info info) {
this.info = info;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
@Override
public String toString() {
return new ToStringBuilder(this).append("info", info).append("data", data).toString();
}
}
Also, in case there are properties which are not specified in Info or Data class. Use @JsonIgnoreProperties(ignoreUnknown = true)
annotation on class to Ignore unknown properties.
Updates
Using annotations could not be very handy if you have to use same Classes say as Hibernate Entities or in other places. Hence, My recommendation is that you perform serialization and deserialization using Dtos
and then later put values from these Dtos to your other objects wherever you need to. You could use good apis like mapstruct
to do such creation of objects.
Upvotes: 0
Reputation: 8308
Your object's keys are lower case and in the json they are upper-camel-case. If this naming scheme is consistent you can just set the naming stategy on the object mapper.
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UpperCamelCaseStrategy);
Upvotes: 1