Jackson具有便利的功能,您可以使用specify custom constructors or static factory methods to use when creating a class, getting parameters from the JSON object。然而,我不知道什么最好的方法是将一个额外的构造函数参数传递给反序列化的对象。例如,我希望能有杰克逊使用JSON来构建和初始化以下类:反序列化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解释为非构造函数属性,而不是编写必须更新的Deserializer一次,我添加或编辑设置属性
- 应该不需要我手动读取和JSON缓冲对象属性(即不重复BeanDeserializer._deserializeUsingPropertyBased)
- 工作与annotation mix-ins
我已经探索过设置自定义CreatorContainers
或DeserializerProviders
,但我还没有想出符合我的要求的方法。
感谢您的回答。 JACKSON-406将不完全解决了使用情况下,我在脑子里(虽然这将是在自己的权利是有用的),但我决定无论如何要采取不同的方法。我敢肯定,这将至少是可能的,但我最终来到了,我不得不为了完成它近乎重复的代码库量不可接受的结论。 – Miles 2011-06-03 06:01:42
(我认为我可以用CreatorContainer创建一个BeanDeserializer,该CreatorContainer返回一个调用非静态方法的自定义PropertyBased构造函数,但当我发现工厂方法静态调用时,放弃了。)ThreadLocal也是一个合理的建议 - 我发布这个问题后我自己想到了。 – Miles 2011-06-03 06:06:03
是的,非常好的侦探工作。 :-)唉,我同意在不修改代码库代码的情况下这个特殊功能很难做到。 – StaxMan 2011-06-03 16:59:00