我正在使用第三方JSON API,它返回如下数据:
{详细信息:{...},...}
我使用Java Jackson将此JSON字符串反序列化为POJO对象,字段声明为:
@JsonProperty(“详细信息”)公共详细信息getDetails(){…}
而
细节
是另一个类。
一切都很好,直到我发现API可能会返回这样的数据:
{详细信息:false,…}
如果详细信息为空,则返回
false
!!!Jackson给了我这个例外:
com.fasterxml.jackson.databind.JsonMappingExc0019:无法从布尔值实例化类型[简单类型,类详细信息]的值;没有单布尔/布尔arg构造函数/工厂方法(通过引用链:...["详细信息"])
那么,如何处理这种JSON字符串呢?如果为空,我只需要将此字段设置为null。
制作一个自定义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;
}
}
来自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. 怎么实现序列化