38

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.

7 Answers 7

97

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)); 
Sign up to request clarification or add additional context in comments.

8 Comments

If this resolves the issue, @user2212726 can you please approve so it can be useful to others as well?
You should give the complete conf. How do you make this "mapper" object you've created yourself to be used by Spring ?
@Tristan just wrap the above piece of code in a method and annotate it with @Bean if you want example, check this - stackoverflow.com/a/32842962/471467
Well, this may fail as you can read below the answer you are quoting.
By "may fail" if you are referring to spring boot then there is a comment which says that use a different name. Makes sense?
|
13

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.

7 Comments

apparently you do not need setters
Depends how you've configured your de/serializer. I think by default Jackson will try bean-style serialisation - based on the getXXX methods available on your classes. Have you tried adding the set method?
yea sure.. it didn't effect .. still the same error
You need to change the JSON fields to begin with a lower case field as well.
@Ungeheuer Don't know to be honest - most docs seem to be on 3rd party sites. Most of my knowledge of Jackson came from having to debug the implementation code every time it did something weird. I've since stopped using it as it's just too idiosyncratic - you invariably have to use annotations everywhere to try and get it to cooperate.
|
7

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

1 Comment

This was much more ideal for me than updating the source JSON file. Thanks @Ashish!
0
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.

Comments

0

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. 

Comments

0

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)); } } 

Comments

-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.

1 Comment

well i did, i called it ResObj, which has the wanted fields, but it still not working, i mean: public class Response { private ResObj resObj; public ResObj getResObj() { return resObj; } .... public class ResObj { private String ClientNum; private String ServerNum; private String IdNum; public String getClientNum() { return ClientNum; } public String getServerNum() { return ServerNum; } public String getIdNum() { return IdNum; } }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.