So I complain. I think it could be done better but I didn’t do any research as why this is the default behavior of Jackson so you can educate me the whole reason behind this design. Since Jackson is the json library SpringMVC has picked, I’m using it.
By default, Jackson will convert any
- public method
- starts with “get”
- takes no arguments
- returns a value
from a POJO to json.
Is it not smart enough to figure out how many of those method are actually truly getters? And how many of them may be convenience methods?
Here’s an example:
public class Foo { private List<String> messsages = new ArrayList<String>(); public List<String> getMesssages() { return messsages; } public void setMesssages(List<String> messsages) { this.messsages = messsages; } public String getLastMessage() { if(getMesssages().isEmpty()) { return ""; } else { return getMesssages().get(getMesssages().size()-1); } } }
@Test public void test() throws JsonGenerationException, JsonMappingException, IOException { ObjectMapper mapper = new ObjectMapper(); Foo foo = new Foo(); String jsonFoo = mapper.writeValueAsString(foo); System.out.println(jsonFoo); Foo convertedFoo = mapper.readValue(jsonFoo, Foo.class); }
This test fails because
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "lastMessage" (Class net.pureessence.Foo), not marked as ignorable
You have some options to get around this issue of course.
Exclude the convenience method so Jackson will NOT convert it
@JsonIgnoreProperties({ "lastMessage" }) public class Foo { ...
or
... @JsonIgnore public String getLastMessage() { ...
Pick which properties Jackson should INCLUDE in its conversion
@JsonPropertyOrder({ "messages" }) @JsonAutoDetect(value=JsonMethod.FIELD) public class Foo { @JsonProperty private List<String> messsages = new ArrayList<String>(); ...
I’m sure there are other options I have not mentioned that you may use to get around the issue.
Either way it requires your close attention and care and most likely tests of your exact json conversion to help you pay attention to how your changes on the POJO will affect your json conversion. I wish the default behavior of Jackson would just convert real properties only. Such as something that have both getters & setters. More here and here.
