Reputation: 1285
i got a deserialization problem:
This is my class:
public class Response {
private Object ResObj;
private int ResInt;
public Object getResObj() {
return ResObj;
}
public int getResInt() {
return ResInt;
}
}
the JSON i want to deserialize is:
{"ResObj":{"ClientNum":"12345","ServerNum":"78945","IdNum":"020252"},"ResInt":0}
I get this exception:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ResObj" , not marked as ignorable (0 known properties: ])
at [Source: java.io.StringReader@1f758500; line: 1, column: 20] (through reference chain: ["ResObj"])
I don't want to add:
@JsonIgnoreProperties(ignoreUnknown = true)
because I want to get the ResObj...
if I add the annotation, it pass but it will set it as null .. which I don't want.
Upvotes: 38
Views: 147297
Reputation: 9408
You need Setter methods to allow Jackson to set the properties, and you need to change the fields in the json to begin with a lower case letter:
public class Response {
private Object ResObj;
private int ResInt;
public Object getResObj() {
return ResObj;
}
public void setResObj(Object ResObj) {
this.ResObj = ResObj;
}
// ...
}
and:
{"resObj":{"clientNum":"12345","serverNum":"78945","idNum":"020252"},"resInt":0}
The reason for the JSON change is that the Jackson bean serialisation will reflect over the class, and when it sees getXyz() and setXyz() methods it will map these to a Json field named "xyz" (and not "Xyz").
I think there are several ways to override this behaviour, one is to use the one of the Jackson annotations.
Upvotes: 13
Reputation: 21551
I tried all the ways mentioned above but in my case, this is the only solution that worked as answered here Solution 2. Here I have enabled @EnableWebMvc
in my spring boot application.
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Autowired
private ObjectMapper objectMapper;// created elsewhere
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// this will add a 2nd MappingJackson2HttpMessageConverter
converters.add(new MappingJackson2HttpMessageConverter(this.objectMapper));
}
}
Upvotes: 0
Reputation: 1599
If you don't want to have a setter in your bean and only use fields and getters, you can use the visibility checker of ObjectMapper
to allow field visibility.
Something like following:
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setVisibility(VisibilityChecker.Std.defaultInstance().withFieldVisibility(JsonAutoDetect.Visibility.ANY));
Upvotes: 96
Reputation: 990
I have sorted this problem using the Jackson library. Here is my code snippet.
**Main Class with JSON String in all lower case:**
public class MainClass {
public static void main(String[] args) throws JsonParseException,
JsonMappingException, IOException {
String jsonStr = "{\r\n" + " \"resObj\": {\r\n" + " \"clientNum\":
\"12345\",\r\n"
+ " \"serverNum\": \"78945\",\r\n" + " \"idNum\":
\"020252\"\r\n" + " },\r\n"
+ " \"resInt\": 0\r\n" + "}";
ObjectMapper mapper = new ObjectMapper();
MyPojo details = mapper.readValue(jsonStr, MyPojo.class);
System.out.println("value of clientNum: " + details.getResObj().getClientNum());
System.out.println("value of getServerNum: " +
details.getResObj().getServerNum());
System.out.println("value of getIdNum: " + details.getResObj().getIdNum());
System.out.println("value of getResInt: " + details.getResInt());
} }
**MyPojo Class:**
public class MyPojo {
private ResObj resObj;
private String resInt;
public ResObj getResObj() {
return resObj;
}
public String getResInt() {
return resInt; } }
**ResObj class:**
public class ResObj {
private String serverNum;
private String idNum;
private String clientNum;
public String getServerNum() {
return serverNum;
}
public String getIdNum() {
return idNum;
}
public String getClientNum() {
return clientNum;
} }
**RESULT**
value of clientNum: 12345
value of getServerNum: 78945
value of getIdNum: 020252
value of getResInt: 0
NOTE: I have removed Setters in classes & there is no effect on the result.
Upvotes: 0
Reputation: 1
public class Response {
public Object ResObj;
public int ResInt;
public Object getResObj() {
return ResObj;
}
public int getResInt() {
return ResInt;
}
}
Use this to resolve the above issue.
Upvotes: 0
Reputation: 1439
I think you should try this
public class Response {
@JsonProperty
private Object ResObj;
@JsonProperty
private int ResInt;
public Object getResObj() {
return ResObj;
}
public int getResInt() {
return ResInt;
}
}
It will resolve your issue with UnrecognizedPropertyExceptions
Upvotes: 7
Reputation: 1
You need to define another class for the information within ResObj {"ClientNum":"12345","ServerNum":"78945","IdNum":"020252"}. Otherwise jackson cannot determine how to deserialize.
Upvotes: -1