Use @JacksonInject with @JsonCreator on a top level map

With Jackson json library, it is possible to deserialize object through the use of the @JsonCreator, and be given the "top level" map representing the input json, as follows:

class MyClass {
    final int field;

    @JsonCreator
    public MyClass(Map<String, Object> map) {
        this.field = (int) map.get("theInt");
    }
}

or even on a 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"));
    }
}

The previous examples can process the following kind of json input:

{
    "key1":"value1",
    "key2":"value2",
    "key3":"value3"
}

This is particularly useful in my case because I would like to deserialize a json which structure I don't know. Being given access to what I call the "top level map" makes things simple.

I would like to deserialize my objects this way as it also allows to create immutable objects, instead of using @JsonAnySetter which doesn't permit this, and @JsonProperty which I can't use as I don't know the properties name in advance as I mentioned earlier.

Then to go further, I would like to inject some configuration in my factory method, and Jackson allows this through the use of @JacksonInject and a call to withInjectableValues(InjectableValues) on the ObjectMapper.

This is eventually the kind of 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;
        // initialize myFields (or any other object) based on the content of map
        // and also make use of the inject conf
        return new MyClass(myFields);
    }
}

Unfortunately, Jackson throws the following kind of exceptions:

  • when trying the trick on the constructor

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 the trick on the factory method

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 could solve the problem?

To sum up the requirements, I need:

  • access to the top level map (don't know the json property names in advance)
  • to create an immutable object (so can't use @JsonAnySetter)
  • to inject some conf to the @JsonCreator decorated constructor or factory method

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 fixed yet)

Answers


Right, you would like to both use "delegating" creator (single argument, into which JSON input is first bound) -- different from "property-based" creator where set of named parameters are passed -- and injectable value(s). This should ideally work, but I think it might not work currently. I think there is a Jira entered for this, so you can check it (http://jira.codehaus.org/browse/JACKSON) out.

Just to make sure: are you using version 1.9.2? There have been some fixes in this are since 1.9.0; which at least would give better error message.


Need Your Help

How to set Home and Path directories in C?

c shell unix

I am programming a small unix shell written in c. I want it to do only some basic commands for now. e.g. ls, pwd, ch

Plotting time series with R

r plot

I'm using R and I've to plot 50 point.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.