I'm trying to parse some Json into an Java object.
Some fields require custom behavior so i tried to use @JsonCreator
on a constructor.
Well, it work, but for the other field annotate with @JsonProperty
are not populated.
Didn't check yet, but i guess my object annotate with @JsonUnwrapped
are not populated either.
In my search, i saw a comment that indicate that it is possible, but i can't figure how, if it is indeed possible.
There is around 400 field in the json, and only 5 or 6 that require custom behavior. So if i can avoid rewriting all constructor... that would be nice !
Exemple of what i tried :
public class MyObjectA {
@JsonProperty("keyField1")
private String myField1;
@JsonUnwrapped
private MyObjectB;
private String[] myField2;
@JsonCreator
public MyObjectA(final Map<String, Object> properties){
myField2 = ... //some Business logic
}
}
Junit :
ObjectMapper mapper = new ObjectMapper();
MyObjectA result = mapper.readValue(getJsonInputStream(JSON_FILE_PATH),MyObjectA.class);
Assert.notNull(result.getMyField1(),"should be populated")
Assert.notNull(result.getMyField2(),"should be populated")
Assert.notNull(result.getMyObjectB(),"should be populated")
Note : without the constructor, the other field are well populated
Here it is. See the difference between commented and non commented @JsonConstructor
usage. I am handling property something as custom handling and leaving name to be called using setName. Hope that helps
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class Jackson2 {
public static void main(String[] args) throws Exception {
final ObjectMapper mapper = new ObjectMapper();
final String jsonInString = "{\"name\":\"hello world\",\"something\":\"from string\"}";
System.out.println(jsonInString);
Foo newFoo = mapper.readValue(jsonInString, Foo.class);
System.out.println(newFoo.getName());
System.out.println(newFoo.getSomething());
}
}
class Foo {
@JsonProperty
private String name;
private String something;
public String getSomething() {
return something;
}
public void setSomething(String something) {
this.something = something;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Foo() {
}
// @JsonCreator
public Foo(final Map<String, Object> properties) {
System.out.println("printing.."+properties);
something = "Something from constructor";
}
@JsonCreator
public Foo(@JsonProperty("something") String something ) {
System.out.println("printing.."+name);
this.something = "Something from constructor appended"+something;
}
}
So idea is that you use @JsonProperty in the constructor argument for properties you want to customize. :)