开发者

Specifying additional arguments to class creation when deserializing JSON

Jackson has the handy feature that you can specify custom constructors or static factory methods to use when creating a class, getting parameters from the JSON object. However, I'm not sure what the best way is to pass an additional constructor argument to a deserialized object. For example, I'd like to be able to have Jackson use this JSON to construct and initialize the following class:

{
    "x": "foo",
    "y": "bar",
    "z": "baz"
}

public class Foo {
    /*
     * conf and x <b>must</b> be supplied at construction time
     */
    @JsonCreator
    public Foo(Configuration conf, @JsonValue("x") String x)

    public String getX();

    public String getY();
    public void setY(String y);
    public String getZ();
    public void setZ(String z);
}

public class SomeMainApplicationClass {
    public Foo loadFoo(InputStream in, Configuration conf) {
        ObjectMapper mapper = new ObjectMapper(/* ??? */);
        /* ??? */
        return mapper.readValue(in, Foo.class);
    }
}

My first instinct was that I needed to create some sort of factory object:

public class FooFactory {
    private final Configuration conf;
    public FooFactory(Configuration conf) {
        this.conf = conf;
    }
    @JsonCreator
    public createFoo(@JsonProperty("x") String x) {
        return new Foo(conf, x);
    }
}

But Jackson doesn't have a straightforward way to plug that in--most of the methods I've found (or annotation-based options) use static factory methods.

The answer must not use global/static variables--I want to configure the Configuration object on a per-ObjectMapper basis.

My prefe开发者_C百科rred answer should:

  • Be brief! I know there are multiple ways to approach this, I'm looking for the simplest one
  • Continue to leverage Jackson's ability to use reflection and interpret data-binding annotations for the non-constructor properties, rather than writing a Deserializer that has to be updated every time I add or edit a settable property
    • Should not require me to manually read and buffer the object properties from JSON (i.e. don't duplicate BeanDeserializer._deserializeUsingPropertyBased)
  • Work with annotation mix-ins

I've explored setting up custom CreatorContainers or DeserializerProviders, but I haven't come up with a method that meets my requirements yet.


There is no current facility to do this; would "ability to inject values during deserialization" (see http://jira.codehaus.org/browse/JACKSON-406) do this? You might want to ask this on Jackson user (or dev) mailing list, as this is one of higher priority features that hopefully will be worked on for Jackson 1.9.

One possibility is to just use @JsonCreator, decorate all parameters with @JsonParameter, and access value from there -- if there is no matching property, you will get null as value. This is not optimal, but if you can access value you need (via ThreadLocal, filled prior to calling deserialization) you would at least be able to solve this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜