Using the Jackson json library, you can deserialize the object using @JsonCreator and get a top-level map representing the json input as follows:
class MyClass { final int field; @JsonCreator public MyClass(Map<String, Object> map) { this.field = (int) map.get("theInt"); } }
or even using the static factory method:
class MyClass { final int field; public MyClass(int theInt) { this.field = theInt; } @JsonCreator static MyClass create(Map<String, Object> map) { return new MyClass((int) map.get("theInt")); } }
In the previous examples, you can handle the following json input:
{ "key1":"value1", "key2":"value2", "key3":"value3" }
This is especially useful in my case, because I would like to deserialize json, which structure I don't know. Giving access to what I call a “top-level map” makes things simple.
I would like to deserialize my objects this way, since it also allows you to create immutable objects instead of using @JsonAnySetter , which does not allow this, and @JsonProperty , which I cannot use, since I do not know the name of the property in advance, as I mentioned earlier.
Then, to continue, I would like to add some configuration to my factory method, and Jackson resolves this with @JacksonInject and calling withInjectableValues(InjectableValues) on ObjectMapper .
In the end, this is the code I would like to use:
class MyClass { final MyField[] myFields; public MyClass(MyField... myFields) { this.myFields = myFields; } @JsonCreator static MyClass create(@JacksonInject("conf") Conf conf, Map<String, Object> map) { MyFields[] myFields;
Unfortunately, Jackson throws the following exceptions:
- when trying to use a constructor trick
JsonMappingException: Argument #1 of constructor [constructor for MyClass, annotations: { JsonCreator=@JsonCreator ()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator
- when trying to use factory trick
JsonMappingException: Argument #1 of factory method [method create, annotations: { JsonCreator=@JsonCreator ()}] has no property name annotation; must have when multiple-paramater static method annotated as Creator
Does anyone know how I can solve the problem?
To summarize, I need:
- access to top level map (don't know json property names in advance)
- to create an immutable object (so you cannot use
@JsonAnySetter ) - to enter some conf into the constructor
@JsonCreator decorated or factory
I cannot change the json input format, which looks like this:
{ "key1":"value1", "key2":"value2", "key3":"value3" }
[EDIT]
This is a known issue: http://jira.codehaus.org/browse/JACKSON-711 (not yet fixed)