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
上一篇
下一篇