java - Jackson 自定义反序列化器在阅读列表时创建空 pojo

标签 java json jackson

我有以下 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);
    }

一切都正确调试,但是生成的 myListC 列表的对象数量增加了一倍,其中偶数个元素包含正确的对象,以及正确的 myReferenceObject 出于持久性(使用我的模块正确反序列化),奇数元素包含空 Pojo,即所有变量都为空值的对象。

通过调试,它永远不会在我的自定义反序列化器中返回 null,因为它每次执行时都能正常工作。问题似乎出在更上游的地方,它插入了空白 myListC 对象。

任何帮助将不胜感激。

谢谢!

最佳答案

您的代码存在逻辑问题。 您想要循环直到到达对象的末尾,但使用 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/

相关文章:

json - 如何使用Apache Spark将JSON文件转换为 Parquet ?

java - 使用jackson将Json对象转换为java对象

java - 是否可以在类级别为不同的数据类型配置 Jackson 自定义反序列化器?

java - 当取消选择 "Add variable attributes to class files"时,Spring @Autowired by name 停止工作

java - MySQL - SQLException : No suitable driver found for jdbc:derby://

json - 替换\"with "的实例

java - 如何避免gson tojson递归

java - 如何使用 Jackson 解析具有可变对象名称的 JSON?

java - JSON 编码字符串的键是什么

在 Java 网络浏览器中工作的 Javascript?