HCRM博客

Jackson Null异常产生的原因是什么?

Jackson 是一个流行的 JSON 处理库,用于在 java 对象和 JSON 数据之间进行转换,在使用 Jackson 时,有时会遇到null 值导致的序列化或反序列化错误,以下是对 Jacksonnull 报错的详细分析:

1、报错原因

Jackson Null异常产生的原因是什么?-图1
(图片来源网络,侵权删除)

实体类中存在 null 属性:当使用 Jackson 将实体类转换为 JSON 时,如果实体类的属性值为 null,默认情况下会将该属性以null 的形式输出到 JSON 字符串中,但在某些场景下,前端组件可能无法正确处理包含null 值的 JSON 数据,从而导致报错。

集合中存在 null 元素:如果实体类中包含集合类型的属性,如 List、Map 等,并且集合中存在 null 元素,在序列化过程中也可能会引发null 相关的错误。

JSON 字符串中存在 null 值:当从 JSON 字符串反序列化为 Java 对象时,JSON 字符串中存在 null 值,而 Java 对象的对应属性类型不允许为 null,或者没有正确处理 null 值的逻辑,就会导致反序列化失败,抛出NullPointerException 等异常。

配置不当:如果没有正确配置 Jackson 的序列化和反序列化策略,可能会导致对null 值的处理不符合预期,从而引发错误,全局配置了不允许序列化 null 值,但在局部场景下又需要序列化 null 值,就可能出现报错的情况。

2、解决方法

实体类中使用注解

Jackson Null异常产生的原因是什么?-图2
(图片来源网络,侵权删除)

@JsonInclude(JsonInclude.Include.NON_NULL):将此注解放在实体类的属性上,如果该属性为 null 则不参与序列化;如果放在类上,则对该类的全部属性起作用。

  • public class User {
  • @JsonInclude(JsonInclude.Include.NON_NULL)
  • private String name;
  • @JsonInclude(JsonInclude.Include.NON_NULL)
  • private String house;
  • // getter 和 setter 方法
  • }

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL):在实体类前增加此注解,可以控制整个类的序列化行为,使其在属性为 null 时不进行序列化。

代码中设置 ObjectMapper

setSerializationInclusion:通过创建 ObjectMapper 对象,并调用其setSerializationInclusion 方法,设置序列化策略,设置为JsonInclude.Include.NON_NULL,表示只序列化非 null 的属性:

  • ObjectMapper mapper = new ObjectMapper();
  • mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
  • User user = new User(1, "", null);
  • String outJson = mapper.writeValueAsString(user);
  • System.out.println(outJson);

自定义序列化器:如果需要更灵活的控制序列化过程,可以自定义序列化器,对于 Map 中的 null key 或 value,可以通过继承 StdSerializer 类来实现自定义的序列化逻辑:

  • public static class NullKeySerializer extends StdSerializer<Object> {
  • public NullKeySerializer() {
  • this(null);
  • }
  • public NullKeySerializer(Class<Object> t) {
  • super(t);
  • }
  • @Override
  • public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) throws IOException, JsonProcessingException {
  • jsonGenerator.writeFieldName("");
  • }
  • }
  • // 使用方法
  • ObjectMapper mapper = new ObjectMapper();
  • mapper.getSerializerProvider().setNullKeySerializer(new NullKeySerializer());
  • Map<String, Object> map = new HashMap<>();
  • map.put(null, "test");
  • System.out.println(mapper.writeValueAsString(map));

全局配置:在 Spring Boot 项目中,可以通过新建配置类的方式来全局配置 Jackson 的行为,创建一个 JacksonConfig 类,并在其中配置 ObjectMapper 的NullValueSerializer,将所有的 null 值转化为空字符串:

  • import com.fasterxml.jackson.databind.ObjectMapper;
  • import com.fasterxml.jackson.databind.ser.std.StdSerializer;
  • import com.fasterxml.jackson.databind.SerializerProvider;
  • import com.fasterxml.jackson.core.JsonGenerator;
  • import org.springframework.context.annotation.Bean;
  • import org.springframework.context.annotation.Primary;
  • import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  • import com.fasterxml.jackson.databind.annotation.JsonSerialize;
  • public class JacksonConfig {
  • @Bean
  • @Primary
  • @ConditionalOnMissingBean(ObjectMapper.class)
  • public ObjectMapper jacksonObjectMapper() {
  • return new ObjectMapper().setDefaultPropertyInclusion(JsonInclude.Include.NON_EMPTY);
  • }
  • }

3、相关问答FAQs

Q: 如果我只想在某个特定的字段上忽略 null 值,而在其他字段上正常处理 null 值,该怎么办?

A: 你可以在该特定字段上使用 @JsonInclude(JsonInclude.Include.NON_NULL) 注解,这样只有这个字段在为 null 时会被忽略,其他字段仍会按照默认的序列化规则进行处理。

Q: 在反序列化过程中,如果遇到 JSON 字符串中的 null 值,如何确保 Java 对象的对应属性不会被设置为 null?

A: 可以在实体类的属性上使用 @JsonSetter 注解,并提供一个自定义的setter方法来处理 null 值,在setter方法中,可以添加逻辑来避免将属性设置为 null,例如赋予默认值或进行其他处理。

本站部分图片及内容来源网络,版权归原作者所有,转载目的为传递知识,不代表本站立场。若侵权或违规联系Email:zjx77377423@163.com 核实后第一时间删除。 转载请注明出处:https://blog.huochengrm.cn/gz/22640.html

分享:
扫描分享到社交APP
上一篇
下一篇