我想在多个不同的上下文中(de-)序列化JSON,这些上下文需要在多个线程中略有不同的Jackson配置。根据Web和类注释中的资源,这应该可以使用从ObjectMapper构造的ObjectWriter和ObjectReader,它具有" base"组态。但是,我还没有成功地从ObjectMapper构建一个不可变的ObjectWriter - 它似乎与mapper一起改变了它的配置。
这是重新配置WRITE_NUMBERS_AS_STRINGS的示例。请将此视为"只是一个例子" WRT我需要ObjectReader和ObjectWriter的解决方案,以及各种配置对象,如@ JacksonInject' ed值,而不仅仅是低级JSON格式选项。
public class Main3 {
public static void main(String[] args) throws Exception {
test(false);
test(true);
}
private static void test(boolean enable) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
ObjectWriter w1 = mapper.writer();
if (enable) {
mapper.enable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
}
ObjectWriter w2 = mapper.writer();
Bean b = new Bean();
b.setX(42);
System.out.println(w1.writeValueAsString(b));
System.out.println(w2.writeValueAsString(b));
}
public static class Bean {
private int x;
/**
* Getter method.
*
* @return the x
*/
public int getX() {
return x;
}
/**
* Setter method.
*
* @param x the x
*/
public void setX(int x) {
this.x = x;
}
}
}
正如您所看到的,我运行相同的测试两次,每次从同一个ObjectMapper创建两个ObjectWriters并使用每个ObjectWrite序列化一个测试bean。在第二次运行中,我为第二个写入器启用了WRITE_NUMBERS_AS_STRINGS。这似乎也影响了第一位作家。
预期产出:
{"x":42}
{"x":42}
{"x":42}
{"x":"42"}
实际输出:
{"x":42}
{"x":42}
{"x":"42"}
{"x":"42"}
还有什么需要将ObjectWriter与ObjectMapper分离吗?不用说,基于这个违反线程安全的示例构建一个示例应该是微不足道的,更不用说ObjectWriter显然不是不可变的。
答案 0 :(得分:2)
文档确实声称读者和作者是不可改变的。如果您发现某些情况不属于您,则应将其报告为错误。
与此同时,您可以复制DB db = mongo.getDB("sample");
DBCollection table = db.getCollection("samplecollection");
DBCursor cursor2 = table.find();
,然后从副本中创建ObjectMapper
。
答案 1 :(得分:0)
对于简短的回答,问题是通过JsonFactory
应用的基础ObjectMapper
的任何更改确实会泄漏。不是因为ObjectWriter
(或ObjectReader
)是可变的,而是因为它们共享可变工厂。
但是:使用with(Feature)
/ without(Feature)
方法可以采用另一种方法避免此类可见更改:
w = w.with(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS); // 要么 w = w.without(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
通过修改构造的JsonGenerator
来工作,而不是重新构造构造生成器的JsonFactory
。