我有以下 json
{
"id":null,
"name":"Myapp",
"description":"application",
"myListA":["java.util.ArrayList",[{
"id":50,
"name":"nameA1",
"myListB":{
"id":48,
"name":"nameB1",
"myListC":["java.util.ArrayList",[{
"id":1250,
"name":"nameC1",
"description":"nameC1_desc",
"myReferenceObject":{
"code":"someCodeA"
}
},{
"id":1251,
"name":"nameC2",
"description":"nameC1_desc",
"myReferenceObject":{
"code":"someCodeB"
}
等等。
我希望用持久层中的项目替换myReferenceObject。
我关注了JacksonHowToCustomDeserializers
我的解串器如下:
public class MyReferenceObjectCodeDeserializer extends JsonDeserializer<MyReferenceObjectBean> {
@Override
public ColumnReferenceBean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jp.getCurrentName();
jp.nextToken();
if ("code".equalsIgnoreCase(fieldname)) {
MyReferenceObjectBean b = MyReferenceObjectServiceImpl.retrieveByCode(jp.getText());
logger.info("returning " +b.toString());
return b;
}
}
logger.info("returning null");
return null;
}
}
我像这样附加模块:
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
SimpleModule module = new SimpleModule("myModule", new Version(1, 0, 0, null));
module.addDeserializer(MyReferenceObjectBean.class, new MyReferenceObjectCodeDeserializer());
mapper.registerModule(module);
try {
return mapper.readValue(serializedJsonString, MyMainObjectBean.class);
} catch (IOException e) {
logger.error("Unable to parse=" + serializedJsonString, e);
}
一切都正确调试,但是生成的 myListCstrong> 列表的对象数量增加了一倍,其中偶数个元素包含正确的对象,以及正确的 myReferenceObject 出于持久性(使用我的模块正确反序列化),奇数元素包含空 Pojo,即所有变量都为空值的对象。
通过调试,它永远不会在我的自定义反序列化器中返回 null,因为它每次执行时都能正常工作。问题似乎出在更上游的地方,它插入了空白 myListCstrong> 对象。
任何帮助将不胜感激。
谢谢!
最佳答案
您的代码存在逻辑问题。 您想要循环直到到达对象的末尾,但使用 return b (if block )中断循环。这意味着在对象流结束之前您不会读取它。
尝试这样的事情(没有尝试,但应该可行)。
public class MyReferenceObjectCodeDeserializer extends JsonDeserializer<MyReferenceObjectBean> {
@Override
public ColumnReferenceBean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
MyReferenceObjectBean b = null;
while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldname = jp.getCurrentName();
jp.nextToken();
if ("code".equalsIgnoreCase(fieldname)) {
b = MyReferenceObjectServiceImpl.retrieveByCode(jp.getText());
logger.info("returning " +b.toString());
}
}
if (b==null) logger.info("returning null");
return b;
}
}
您还可以看看Genson http://code.google.com/p/genson/如果你可以改变 jackson 。除了一些其他功能之外,它应该更容易使用。以下是如何使用 genson 解决问题(在本例中,它与 jackson 非常相似):
public class MyReferenceObjectCodeDeserializer implements Deserializer<MyReferenceObjectBean> {
public MyReferenceObjectBeandeserialize(ObjectReader reader, Context ctx) throws TransformationException, IOException {
MyReferenceObjectBean b = null;
reader.beginObject();
while (reader.hasNext()) {
reader.next();
if ("code".equalsIgnoreCase(reader.name()))
b = MyReferenceObjectServiceImpl.retrieveByCode(reader.valueAsString());
}
reader.endObject();
return b;
}
}
// register it
Genson genson = new Genson.Builder().withDeserializers(new MyReferenceObjectCodeDeserializer()).create();
MyClass myClass = genson.deserialize(json, MyClass.class);
关于java - Jackson 自定义反序列化器在阅读列表时创建空 pojo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13119529/