Skip to content

Jackson相关注解

@JsonInclude

  • Include.ALWAYS:始终包含属性,无论其值是什么。这是默认行为,即使属性值为 null 或者为空,也会被包含在序列化后的 JSON 中
  • Include.NON_NULL:只包含非null值。如果属性值为null,则不会出现在序列化后的JSON中
  • Include.NON_ABSENT:只包含非absent 。这个选项对于一些特殊的类型,比如Java 8的Optional。如果Optional对象为空(即Optional.empty()),则不会包含在 JSON 中
  • Include.NON_EMPTY:只包含非空值。这意味着如果属性值是空字符串、空集合(如空列表、空数组、空Map等)或者null,则不会出现在序列化后的JSON中
  • Include.NON_DEFAULT:只包含非默认值。如果属性值是其类型的默认值(比如,对于整数是0,对于布尔值是false),则不会包含在JSON中
  • Include.CUSTOM:自定义包含策略。可以通过实现JsonInclude.Include接口来定义自己的包含策略
  • Include.WHEN_NEEDED:只在没有显式指定@JsonProperty注解的情况下包含属性。如果使用了@JsonProperty(access = Access.READ_WRITE)或其他访问级别,则该属性会被包含在序列化后的JSON中
java
import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.List;

public class Example {
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private String name;

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<String> items;
}

全局配置

配置ObjectMapper对象的转化器规则:

java
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration // 标记为一个配置类
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 遍历所有已注册的 HttpMessageConverter
        for (HttpMessageConverter<?> converter : converters) {
            // 找到 MappingJackson2HttpMessageConverter
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                MappingJackson2HttpMessageConverter jacksonConverter = (MappingJackson2HttpMessageConverter) converter;
                // 自定义 ObjectMapper
                jacksonConverter.getObjectMapper()
                        .setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略值为 null 的字段
                break;
            }
        }
    }
}

Json序列化时忽略所有为null的字段

@JsonIgnore

完全忽略一个字段,即在序列化和反序列化过程中都不会处理这个字段

java
import com.fasterxml.jackson.annotation.JsonIgnore;

public class User {
    private String username;

    @JsonIgnore
    private String password;

    // 其他字段和方法
}

@JsonProperty

用于指定序列化和反序列化时JSON字段的名称

java
import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    @JsonProperty("user_name")
    private String name;
    // 其他字段和方法
}

@JsonFormat

用于指定日期和时间的格式。当序列化和反序列化日期或时间字段时,可以使用这个注解来指定输出的格式

java
import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Date;

public class Event {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startTime;
    // 其他字段和方法
}

@JsonSerialize、@JsonDeserialize

这两个注解用于自定义序列化和反序列化过程

  • 序列化:是指将对象转换为一种格式,通常是字符串格式,以便可以存储或通过网络传输。在Java 中,这通常意味着将对象转换为 JSON 格式。序列化的目的是为了能够在以后某个时间点重新创建相同对象的状态
  • 反序列化:是序列化的逆过程,它将字符串格式的数据转换回对象。这意味着从 JSON 字符串中读取数据,并将其转换回原始的 Java 对象
java
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class CustomSerializerExample {
    @JsonSerialize(using = CustomSerializer.class)
    @JsonDeserialize(using = CustomDeserializer.class)
    private CustomType customField;
    // 其他字段和方法
}

CustomSerializer.java

java
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;

// 创建自定义序列化器
public class CustomSerializer extends StdSerializer<CustomType> {

    public CustomSerializer() {
        this(null);
    }

    public CustomSerializer(Class<CustomType> t) {
        super(t);
    }

    @Override
    public void serialize(CustomType value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        // 将 CustomType 的数据写入 JSON
        jsonGenerator.writeStartObject(); // 开始一个 JSON 对象
        jsonGenerator.writeStringField("data", value.getData()); // 写入字段 "data"
        jsonGenerator.writeEndObject(); // 结束 JSON 对象
    }
}

CustomDeserializer.java

java
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;

// 创建自定义反序列化器
public class CustomDeserializer extends StdDeserializer<CustomType> {
    public CustomDeserializer() {
        this(null);
    }

    public CustomDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public CustomType deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        String data = null;
        while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
            String fieldName = jsonParser.getCurrentName();
            if ("data".equals(fieldName)) {
                jsonParser.nextToken(); // 移动到字段的值
                data = jsonParser.getText();
                break;
            }
            jsonParser.nextToken(); // 跳过不需要的字段
        }
        return new CustomType(data);
    }
}

输入对象:

java
CustomSerializerExample example = new CustomSerializerExample();
example.setCustomField(new CustomType("Hello, Jackson!"));

序列化结果:

{"customField":{"data":"Hello, Jackson!"}}

反序列化结果:

反序列化结果: CustomSerializerExample{customField=CustomType{data='Hello, Jackson!'}}

@JsonNaming

自定义JSON序列化和反序列化时的字段命名策略。它允许你为类或字段指定一个命名策略(Naming Strategy),从而控制 JSON 中字段名的格式,Jackson提供了一些内置的命名策略

命名策略描述示例转换
PropertyNamingStrategies.LowerCamelCaseStrategy默认的驼峰命名法(不改变字段名)userNameuserName
PropertyNamingStrategies.SnakeCaseStrategy蛇形命名法userNameuser_name
PropertyNamingStrategies.UpperCamelCaseStrategy首字母大写的驼峰命名法userNameUserName
PropertyNamingStrategies.KebabCaseStrategy短横线命名法(kebab-case)userNameuser-name
PropertyNamingStrategies.LowerCaseStrategy全小写命名法userNameusername
PropertyNamingStrategies.UpperSnakeCaseStrategy全大写的蛇形命名法userNameUSER_NAME

@JsonRootName

用于在序列化和反序列化时为JSON数据添加或识别一个根元素(root element),需要结合ObjectMapperWRAP_ROOT_VALUE特性才能生效,mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE)启用了根元素解析功能

java
import com.fasterxml.jackson.annotation.JsonRootName;

@JsonRootName(value = "user")
public class User {
    private String name;
    // 其他字段和方法
}