在反序列化JSON时指定类创建的其他参数

时间:2011-05-27 17:06:56

标签: java json jackson

杰克逊有一个方便的功能,你可以specify custom constructors or static factory methods to use when creating a class, getting parameters from the JSON object。但是,我不确定将其他构造函数参数传递给反序列化对象的最佳方法是什么。例如,我希望杰克逊能够使用这个JSON来构建和初始化以下类:

{
    "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);
    }
}

我的第一直觉是我需要创建某种工厂对象:

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);
    }
}

但杰克逊没有一种简单的方法来插入 - 我发现的大多数方法(或基于注释的选项)都使用静态工厂方法。

答案不得使用全局/静态变量 - 我想按照ObjectMapper基础配置配置对象。

我的首选答案应该

  • 简短!我知道有多种方法可以解决这个问题,我正在寻找最简单的方法
  • 继续利用Jackson的能力使用反射并将data-binding annotations解释为非构造函数属性,而不是编写每次添加或编辑可设置属性时都必须更新的反序列化器
    • 不应要求我从JSON手动读取和缓冲对象属性(即不要复制BeanDeserializer._deserializeUsingPropertyBased)
  • 使用annotation mix-ins

我已经探索过设置自定义CreatorContainersDeserializerProviders,但我还没有提出符合我要求的方法。

1 个答案:

答案 0 :(得分:1)

目前没有设施可以做到这一点;将“在反序列化期间注入值的能力”(见http://jira.codehaus.org/browse/JACKSON-406)这样做?您可能想在Jackson用户(或开发)邮件列表中询问此问题,因为这是有望为Jackson 1.9工作的更高优先级功能之一。

一种可能性就是使用@JsonCreator,用@JsonParameter装饰所有参数,并从那里访问值 - 如果没有匹配属性,你将得到null作为值。这不是最佳选择,但如果您可以访问所需的值(通过ThreadLocal,在调用反序列化之前填充),您至少可以解决此问题。