当前位置: 首页 > 知识库问答 >
问题:

java jackson反序列化程序如何处理同一字段上的布尔值和对象

云啸
2023-03-14

我正在使用第三方JSON API,它返回如下数据

{详细信息:{...},...}

我使用Java Jackson将此JSON字符串反序列化为POJO对象,字段声明为:

@JsonProperty(“详细信息”)公共详细信息getDetails(){…}

细节是另一个类。

一切都很好,直到我发现API可能会返回这样的数据:

{详细信息:false,…}

如果详细信息为空,则返回false!!!Jackson给了我这个例外:

com.fasterxml.jackson.databind.JsonMappingExc0019:无法从布尔值实例化类型[简单类型,类详细信息]的值;没有单布尔/布尔arg构造函数/工厂方法(通过引用链:...["详细信息"])

那么,如何处理这种JSON字符串呢?如果为空,我只需要将此字段设置为null。


共有2个答案

周兴朝
2023-03-14

制作一个自定义JsonDeserializer来处理对详细信息对象的反序列化,如果得到false,则返回null;如果对象是实际对象,则将其传递给默认反序列化器。伪代码:

public class CustomDeserializer extends JsonDeserializer<Details>{
    @Override
    public Details deserialize(JsonParser jsonParser, DeserializationContext ctx){
        //if object use default deserializer else return null
    }
}

您还必须编写ObjectMapperProvider来注册反序列化程序,如下所示:

@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper>{
    private ObjectMapper mapper;

    public ObjectMapperProvider(){
        mapper = new ObjectMapper();
        SimpleModule sm = new SimpleModule();
        sm.addDeserializer(Details.class, new CustomDeserializer());
        mapper.registerModule(sm);
    }

    public ObjectMapper getContext(Class<?> arg0){
        return mapper;
    }
}
谢灵均
2023-03-14

来自Jackson的错误消息提示库已经构建了对静态工厂方法的支持。这(可能)是一个比自定义反序列化程序更简单的解决方案:

我创建了这个示例POJO,使用了一个静态工厂方法,并加了注释,以便Jackson使用它:

public class Details {
    public String name;  // example property

    @JsonCreator
    public static Details factory(Map<String,Object> props) {

        if (props.get("details") instanceof Boolean) return null;

        Details details = new Details();
        Map<String,Object> detailsProps = (Map<String,Object>)props.get("details");
        details.name = (String)detailsProps.get("name");
        return details;
    }
}

测试方法:

public static void main(String[] args)
{
    String fullDetailsJson = "{\"details\": {\"name\":\"My Details\"}} ";
    String emptyDetailsJson = "{\"details\": false} ";
    ObjectMapper mapper = new ObjectMapper();
    try {
        Details details = mapper.readValue(fullDetailsJson, Details.class);
        System.out.println(details.name);
        details = mapper.readValue(emptyDetailsJson, Details.class);
        System.out.println(details);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

结果如预期:

My Details
null
 类似资料:
  • 我有一个这样的财产: 我需要在其他类中解析时将其作为字符串 但这里是布尔值。 我想我需要做这样的事情。 还有一个像这样的班级 但找不到合适的例子。 这也是

  • 我想进一步说明这个问题是关于什么的,我已经漫游了一个小时了,但没有找到任何东西。 更糟糕的是,正如您所看到的,该属性是final(这就是为什么我热衷于通过反序列化在实例化时使用Jackson反射能力)。我已经阅读了关于以不同的方式注释setter和getter的潜在解决方案,但如果可能的话,我希望将此属性保留为最终属性。如果不可能,我会接受一个非最终财产。 我希望答案不建议自定义序列化/反序列化,

  • 问题内容: 我有一个像这样的课程: 我想序列化它们的列表: 当我进行序列化时,动物属性的类型信息将丢失。有没有一种方法可以某种方式安装解析器侦听器,以便在遇到列表中的每个元素时提供正确的类进行反序列化?这就是手动提供描述类类型的字符串的想法。 谢谢 问题答案: Gson项目代码库中的RuntimeTypeAdapter据说可以很好地用于多态序列化和反序列化。我认为我尚未尝试使用它。有关更多信息,请

  • 我在Spring Kafka设置中使用Avro和模式注册表。 我想以某种方式处理,它可能在反序列化过程中引发。 我找到了以下两个资源: https://github.com/spring-projects/spring-kafka/issues/164 有人知道如何在Spring Boot中捕获吗? 我使用的是Spring Boot 2.0.2 编辑:我找到了解决办法。

  • 问题内容: 我有一个问题。我想使用JAXB将一个对象转换为另一个对象。就像在中,我有一个class 和另一个class ,它们都有相同的参数,实际上都是相同的(复制粘贴),但是包不同。我想使用进行它们之间的转换。 怎么做,请帮帮我。 问题答案: 您可以执行以下操作。 注意: 不需要利用JAXBSource将数据具体化为XML。 它在对象模型上不需要任何注释。 com.home.Student co

  • 本文向大家介绍java对象的序列化和反序列化,包括了java对象的序列化和反序列化的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java对象的序列化和反序列化,供大家参考,具体内容如下 1. 什么是序列化        将对象转换为字节流保存起来,比如保存到文件里,并在以后还原这个对象,这种机制叫做对象序列化。(补充一句:把对象保存到永久存储设备上称为持久化) 2. 怎么实现序列化