Skip to content

Jackson

导入依赖

xml
<!--SpringBoot的web启动器会通过依赖传导,将Jackson导入,即不需要导入下方依赖-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.4.2</version>
    <scope>compile</scope>
</dependency>

想要使用 Jackson 的 JSON 转换 API 只需要声明一个 ObjectMapper 对象,ObjectMapper 是线程安全的类,所以为了运行效率我们通常声明一个全局的 Jackson 对象即可

java
//将对象放进容器,通过自动注入获取该对象
@Configuration
class JsonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
    }
}

对象转JSON字符串

简单转换

主要使用 ObjectMapperwriteValueAsString() 方法,将需要转换的对象转入即可(可以是一个普通的类对象,也可以是一个集合和 Map 对象)

java
ObjectMapper objectMapper = new ObjectMapper();
User user = User.builder().name("张三").age(18).build();
// user 对象转 JSON 字符串
String json = objectMapper.writeValueAsString(user);
System.out.println(json);

忽略NULL值

设置ObjectMapper的默认值

java
public ObjectMapper setSerializationInclusion(JsonInclude.Include incl);

//默认值是 ALWAYS,即默认会序列化类中的所有属性字段(不包括 static)。
public enum Include {
    //包含所有字段
    ALWAYS,
    //忽略值为NULL的字段
    NON_NULL,
    //对于Java8的Optional类型,只有存在值的Optional属性才会被序列化。
    NON_ABSENT,
    //忽略值为 空 的字段. 如字符串: "", 数组或集合: [].
    NON_EMPTY,   
    //只有属性值不等于默认值的属性才会被序列化。例如,对于int类型,只有属性值不等于0时,才会被序列化。
    NON_DEFAULT, 
    //用户自定义的策略,需要配合`JsonInclude.Value`使用。
    CUSTOM,
    //使用全局的默认配置。
    USE_DEFAULTS;
}

通过setSerializationInclusion设置

java
ObjectMapper objectMapper = new ObjectMapper();
// 忽略值为 NULL 的字段
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

// 忽略值为 "空" 的字段. 如字符串: "", 数组或集合: []
// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

User user = User.builder().name("张三").age(18).build();

String json = objectMapper.writeValueAsString(user);

System.out.println(json);

忽略指定字段

使用 @JsonIgnoreProperties 注解

java
//接受一个数组字符串,每个字符串代表类中的一个属性字段,将想要忽略的字段以字符串数组的形式写上即可
@JsonIgnoreProperties({"name", "age"})
public class User {

    private String name;

    private Integer age;

    private LocalDate date;

    private LocalTime time;

    private LocalDateTime dateTime;

    private List<String> tags;
}


//也可以写在字段上,直接忽略这个字段
public class User {
    @JsonIgnoreProperties
    private String name;

    private Integer age;

    private LocalDate date;

    private LocalTime time;

    private LocalDateTime dateTime;

    private List<String> tags;
}

使用 FilterProvider

SimpleBeanPropertyFilter.filterOutAllExcept() API,该 API 指的是除了指定字段都忽略。即除了我们输入的 name 字段都被忽略掉

设置了一个过滤器ID:userPropertyFilter,我们还需要在 User 类上使用 @JsonFilter("userPropertyFilter") 注解

java
ObjectMapper objectMapper = new ObjectMapper();

// 创建一个过滤器,该过滤器将过滤掉除 "name" 字段以外的所有字段
SimpleBeanPropertyFilter propertyFilter = SimpleBeanPropertyFilter.filterOutAllExcept("name");

// 创建一个过滤器提供者并添加我们的过滤器
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("userPropertyFilter", propertyFilter);

// 将过滤器提供者设置到 ObjectMapper 对象中
objectMapper.setFilterProvider(filterProvider);
User user = User.builder().name("张三").age(18).build();
String json = objectMapper.writeValueAsString(user);
System.out.println(json);


@JsonFilter("userPropertyFilter")
public class User {

    // ...
}

对象序列化到本地文件

Jackson 不仅仅能够将一个对象序列化成一个 Json 字符串,还能够将序列化的结果输出到本地文件、IO流以及二进制数据等等。

java
// 将Java对象序列化为JSON,并将JSON写入DataOutput流
public void writeValue(DataOutput out, Object value);

// 将Java对象序列化为JSON,并将JSON写入Writer
public void writeValue(Writer w, Object value);

// 将Java对象序列化为JSON,并将JSON转换为字节数组
public byte[] writeValueAsBytes(Object value);

// 将Java对象序列化为JSON,并将JSON写入文件
public void writeValue(File resultFile, Object value);


ObjectMapper objectMapper = new ObjectMapper();
File file = new File("/Users/xx/Desktop/test.txt");
User user = User.builder().name("张三").age(18).date(LocalDate.now()).build();
objectMapper.writeValue(file, user);

JSON字符串转对象

字符串转对象

JSON字符串转对象(通常称为反序列化)主要使用的是 ObjectMapper#readValue 方法

java
TypeReference 相比较Class更加强大,因为Class只能接受单类型对象,如果想要将Json字符串转换为集合或者Map对象 Class是实现不了的,这种情况下只能使用TypeReference。

public <T> T readValue(String content, Class<T> valueType);
public <T> T readValue(String content, JavaType valueType);
public <T> T readValue(String content, TypeReference valueTypeRef);

字符串转class

java
String jsonStr = "{\"name\":\"张三\",\"age\":18,\"date\":null,\"time\":null,\"dateTime\":null,\"tags\":null}";

ObjectMapper objectMapper = new ObjectMapper();

User user = objectMapper.readValue(jsonStr, User.class);
//User user = objectMapper.readValue(jsonStr, new TypeReference<User>(){});
System.out.println(user);

字符串转 List

JSON 数组形式的字符串转集合,想要解决这个问题就不能使用 Class 重载方法了,而要使用 TypeReference 重载方法

java
String jsonStr = "[{\"name\":\"张三\",\"age\":18,\"date\":null,\"time\":null,\"dateTime\":null,\"tags\":null},{\"name\":\"李四\",\"age\":20,\"date\":null,\"time\":null,\"dateTime\":null,\"tags\":null}]";

ObjectMapper objectMapper = new ObjectMapper();

// 注意 TypeReference 的用法
List<User> user = objectMapper.readValue(jsonStr, new TypeReference<List<User>>(){});
System.out.println(user);

字符串转 Map

java
String jsonStr = "[{\"name\":\"张三\",\"age\":18,\"date\":null,\"time\":null,\"dateTime\":null,\"tags\":null},{\"name\":\"李四\",\"age\":20,\"date\":null,\"time\":null,\"dateTime\":null,\"tags\":null}]";

ObjectMapper objectMapper = new ObjectMapper();

// 注意 TypeReference 的用法
Map<String, String> map = objectMapper.readValue(jsonStr, new TypeReference<Map<String, String>>() {});
System.out.println(user);

文件转对象

Jackson不仅能够将普通的JSON字符串反序列化为对象,还能够直接从文件中读取 JSON 内容反序列化成对象。

java
public <T> T readValue(File src, Class<T> valueType);
public <T> T readValue(File src, JavaType valueType);
public <T> T readValue(File src, TypeReference valueTypeRef);

//文件并不限制一定是 json 文件,只要文件内容是 JSON 格式就能够正常解析,比如 txt 文件
ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(new File("/Users/Desktop/test.json"), User.class);

网络文件转对象

java
public <T> T readValue(URL src, Class<T> valueType);
public <T> T readValue(URL src, JavaType valueType);
public <T> T readValue(URL src, TypeReference valueTypeRef);

ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(new URL("file:/Users/Desktop/test.txt"), User.class);

二进制流转对象

java
public <T> T readValue(InputStream src, Class<T> valueType);
public <T> T readValue(InputStream src, JavaType valueType);
public <T> T readValue(InputStream src, TypeReference valueTypeRef);

ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(new FileInputStream(new File("/Users/Desktop/test.txt")), User.class);

JAVA日期格式问题

默认序列化与反序列化规则

java
ObjectMapper objectMapper = new ObjectMapper();

User user = User.builder().name("张三").age(18)
    	        .time(LocalTime.now())
                .date(LocalDate.now())
                .dateTime(LocalDateTime.now())
                .build();

String json = objectMapper.writeValueAsString(user);

序列化结果

java
{
    "name": "张三",
    "age": 18,
    "date": {
        "year": 2021,
        "month": "JULY",
        "era": "CE",
        "dayOfYear": 207,
        "dayOfWeek": "MONDAY",
        "leapYear": false,
        "dayOfMonth": 26,
        "monthValue": 7,
        "chronology": {
            "id": "ISO",
            "calendarType": "iso8601"
        }
    },
    "time": {
        "hour": 13,
        "minute": 38,
        "second": 52,
        "nano": 514000000
    },
    "dateTime": {
        "dayOfYear": 207,
        "dayOfWeek": "MONDAY",
        "month": "JULY",
        "dayOfMonth": 26,
        "year": 2021,
        "monthValue": 7,
        "hour": 13,
        "minute": 38,
        "second": 52,
        "nano": 515000000,
        "chronology": {
            "id": "ISO",
            "calendarType": "iso8601"
        }
    },
    "tags": null
}

反序列化结果

java
//将dateTime转换为DateTime类型字段会抛出错误
{
    "name": "张三",
    "age": 18,
    "date": null,
    "time": null,
    "dateTime": "2021-07-26 18:35:02",
    "tags": null
}

@JsonFormat

配置形式只能格式化 java.util.Date 日期格式~

java
public class User {
    private String name;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate date;
    private LocalTime time;
    private LocalDateTime dateTime;
    private List<String> tags;
}

时区问题

java
@Setter
@Getter
@ToString
class User {
    private String username;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date date;   
}

//将时间转换为2021-09-25 10:48:30,结果会变为 "date" : "2021-09-25 02:48:38",时间差了八个小时
//因为Jackson 的 com.fasterxml.jackson.annotation.JsonFormat 注解在做日期格式化时默认选择的是 UTC 时区,而不是 JVM 读取的操作系统的时区。

public static void main(String[] args) throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    
    // 格式化输出,在将Java对象序列化为JSON字符串时,会添加必要的空格和换行,使得生成的JSON字符串更易于人类阅读
    objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
    //未添加格式化输出:{"name":"John","age":30,"city":"New York"}
    /*
    {
        "name": "John",
        "age": 30,
        "city": "New York"
    }
    */
    
    // 设置时区,TimeZone.getDefault()为JVM的默认时区
    objectMapper.setTimeZone(TimeZone.getDefault());

    User user = new User();
    user.setUsername("zhangsan");
    user.setDate(new Date());

    System.out.println(objectMapper.writeValueAsString(user));
}

JavaTimeModule

导入依赖
xml
<!--SpringBoot-web的启动器通过依赖传递导入了这个依赖-->
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>${jaskon.version}</version>
</dependency>

使用
java
//注册Module
public ObjectMapper registerModule(Module module);

// 序列化使用
public <T> SimpleModule addSerializer(Class<? extends T> type, JsonSerializer<T> ser);

// 反序列化使用
public <T> SimpleModule addDeserializer(Class<T> type, JsonDeserializer<? extends T> deser);


//将对象放进容器,通过自动注入获取该对象
@Configuration
class JsonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        // LocalTime 序列化和反序列化配置
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter));

        // LocalDate 序列化和反序列化配置
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));

        // LocalDateTime 序列化和反序列化配置
        DateTimeFormatter datetimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(datetimeFormatter));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(datetimeFormatter));

        //注册到ObjectMapper中
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(javaTimeModule);      
        
        //返回全局单例模式
        return objectMapper;
    }
}

自定义序列化和反序列化

这种配置方式与上面的 JavaTimeModule 本质上是一样的。主要是扩展 com.fasterxml.jackson.databind.JsonSerializercom.fasterxml.jackson.databind.JsonDeserializer 来实现自定义某个类的序列化问题。

序列化

java
//序列化 LocalDate
public class LocalDateJsonSerializer extends JsonSerializer<LocalDate> {
    @Override
    public void serialize(LocalDate date, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.CHINA)));
    }
}

//序列化 LocalTime
public class LocalTimeJsonSerializer extends JsonSerializer<LocalTime> {
    @Override
    public void serialize(LocalTime time, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(time.format(DateTimeFormatter.ofPattern("HH:mm:ss", Locale.CHINA)));
    }
}

//序列化 LocalDateTime
public class LocalTimeJsonSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime datetime, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeString(datetime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA)));
    }
}

反序列化

java
//反序列化LocalDate
public class LocalDateJsonDeserializer extends JsonDeserializer<LocalDate> {
    @Override
    public LocalDate deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        return LocalDate.parse(parser.getText(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }
}

//反序列化LocalTime
public class LocalTimeJsonDeserializer extends JsonDeserializer<LocalTime> {
    @Override
    public LocalTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        return LocalTime.parse(parser.getText(), DateTimeFormatter.ofPattern("HH:mm:ss"));
    }
}

//反序列化LocalDateTime
public class LocalDateTimeJsonDeserializer extends JsonDeserializer<LocalDateTime> {
    @Override
    public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        return LocalDateTime.parse(parser.getText(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}

使用自定义序列化

java
public class User {

    private String name;

    private Integer age;

    @JsonSerialize(using = LocalDateJsonSerializer.class)
    @JsonDeserialize(using = LocalDateJsonDeserializer.class)
    private LocalDate date;

    @JsonSerialize(using = LocalTimeJsonSerializer.class)
    @JsonDeserialize(using = LocalTimeJsonDeserializer.class)
    private LocalTime time;

    @JsonSerialize(using = LocalDateTimeJsonSerializer.class)
    @JsonDeserialize(using = LocalDateTimeJsonDeserializer.class)
    private LocalDateTime dateTime;

    private List<String> tags;
}

SpringMVC 的消息转换器中使用

借助 SpringMVC 的 Jackson 消息转换器

java
private static void configureObjectMapper4Jsr310(ObjectMapper objectMapper) {
    
    // 创建一个Jackson2ObjectMapperBuilder对象
    Jackson2ObjectMapperBuilder mapperBuilder = new Jackson2ObjectMapperBuilder();
    
    // 为LocalDate类型设置序列化器
    mapperBuilder.serializerByType(LocalDate.class, new LocalDateJsonSerializer());
    // 为LocalTime类型设置序列化器
    mapperBuilder.serializerByType(LocalTime.class, new LocalTimeJsonSerializer());
    // 为LocalDateTime类型设置序列化器
    mapperBuilder.serializerByType(LocalDateTime.class, new LocalDateTimeJsonSerializer());

    // 为LocalDate类型设置反序列化器
    mapperBuilder.deserializerByType(LocalDate.class, new LocalDateJsonDeserializer());
    // 为LocalTime类型设置反序列化器
    mapperBuilder.deserializerByType(LocalTime.class, new LocalTimeJsonDeserializer());
    // 为LocalDateTime类型设置反序列化器
    mapperBuilder.deserializerByType(LocalDateTime.class, new LocalDateTimeJsonDeserializer());

    // 配置ObjectMapper对象,将Jackson2ObjectMapperBuilder中的配置应用到提供的ObjectMapper实例上。
    mapperBuilder.configure(objectMapper);
}

常用类型

JsonNode

代表了JSON文档中的一个节点,可以是一个JSON对象、数组、字符串、数字、布尔值或者null。

java
ObjectMapper objectMapper = new ObjectMapper();
//将对象转换为JSONNode
User user = User.builder().name("张三").age(18).date(LocalDate.now()).build();
JsonNode jsonNode = objectMapper.valueToTree(user);


//将JSON字符串转换为JsonNode
String jsonStr = "{\"name\":\"张三\",\"age\":18,\"date\":null,\"time\":null,\"dateTime\":null,\"tags\":null}";
JsonNode jsonNode = objectMapper.readTree(jsonStr);

ObjectNode

ObjectnNode 继承至 JsonNode。有了 ObjectNode 对象我们就能够调用它的相关 put 对象进行设置一个 Key -Value了。

java
//ObjectMapper 通常都是声明为全局对象,这个全局对象都是做过相应配置的。所以在创建 ObjectNode 时最好使用下面的方式
//ObjectNode是可变的,本身并不是线程安全的
ObjectNode objectNode = new ObjectNode(objectMapper.getNodeFactory());
java
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = objectMapper.createObjectNode();
//向ObjectNode中添加数据
objectNode.put("money", new BigDecimal("100.00"));


//调用 get(Key) 方法返回的是一个JsonNode 对象。
JsonNode jsonNode = objectNode.get("money");
//想要获取具体的数据类型需要相应的转换,比如上面设置的 money 是个 BigDecimal 类型对象,就需要调用 Decimal 方法进行转换:
BigDecimal money = jsonNode.decimalValue();
    
//得到字符串数据    
String jsonNode = objectNode.get("name").textValue();

//得到MyClass对象
objectMapper.treeToValue(node, MyClass.class);

ArrayNode

ObjectNode 的功能类似于 Map,而 ArrayNode 就是 List 了。

java
ArrayNode arrayNode = objectMapper.createArrayNode();
ArrayNode arrayNode = new ArrayNode(objectMapper.getNodeFactory())

属性配置

自定义序列化

通常在序列化时给前端返回具体的 code 码,即输出如下:{ "payMethod" : 2},可以使用@JsonValue注解。注意,不能同时在多个属性上使用 @JsonValue 注解,否则会抛出异常。

java
//在序列化时指定哪个 Java 属性或方法的返回值应该被用作 JSON 对象的值。
//下述对象序列化后,返回的将会是code的值,如果想要输出的是具体的描述文字就在 phrase 属性上加上 @JsonValue 注解即可
public enum PayMethod {
    /** 支付宝 */
    ALI_PAY(1, "支付宝"),
    /** 微信 */
    WECHA_PAY(2, "微信");
    @JsonValue
    private final int code;
    private final String phrase;
    PayMethod(int code, String phrase) {
        this.code = code;
        this.phrase = phrase;
    }
}

自定义反序列化

默认情况下,Jackson 在反序列化时会调用类的无参构造方法。现在使用 @JsonCreator 注解我们就可以随意定义了。

java
public class Person {
    private final String name;
    private final int age;

    @JsonCreator
    //@JsonProperty 注解用于指定每个参数对应的 JSON 属性的名字。当 Jackson 库反序列化一个 JSON 字符串为 Person 对象时,它会使用这个构造函数,并确保 name 属性的值是大写的。
    public Person(@JsonProperty("name") String name, @JsonProperty("age") int age) {
        this.name = name.toUpperCase();
        this.age = age;
    }
}

JSON 字符串格式化输出

java
ObjectMapper objectMapper = new ObjectMapper();
    
// 格式化输出,在将Java对象序列化为JSON字符串时,会添加必要的空格和换行,使得生成的JSON字符串更易于人类阅读
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
//未添加格式化输出:{"name":"John","age":30,"city":"New York"}
/*
{
   "name": "John",
   "age": 30,
   "city": "New York"
}
*/

transient 字段的处理

比如我们有一个 User 对象,在该对象中有一个 password 属性字段。在序列化保存时,如果不做处理那么相应的密码就会被保存到磁盘上,那么对于这个用户而言是绝大的风险。而transient 是 Java 中的一个关键字。使用该关键字标识的属性字段在序列化与反序列化时会被忽略(如果不做特殊处理的话),但是 Jackson 在将对象序列化时是有问题的,因为它默认是不会对 transient 属性字段进行特殊处理的。之所以 password 字段没有被忽略的原因是因为 Jackson 在序列化时使用的是 setter/getter 方法进行属性推断,而不是具体的属性字段

ObjectMapper开启配置项

java
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);

setVisibility

java
// 创建一个ObjectMapper对象
ObjectMapper objectMapper = new ObjectMapper();

// 设置ObjectMapper的可见性
objectMapper.setVisibility(
    objectMapper.getSerializationConfig()
    //获取默认的可见性检查器
    .getDefaultVisibilityChecker()
    //设置字段的可见性为ANY,表示所有字段都可见
    .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
    //设置getter方法的可见性为NONE,表示getter方法不可见
    .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
);

SpringBoot配置

properties
#如果在SpringBoot项目中,仅需添加下方配置即可
spring.jackson.mapper.propagate-transient-marker=true

序列化时指定属性排序

  • 默认的序列化顺序,根据属性声明的顺序输出。
  • 自定义序列化顺序,根据指定的value[]定义属性顺序输出。
java
// 定义属性顺序
@JsonPropertyOrder({"sign", "age", "name"})
public class Basic {
    //...
}

驼峰转换

针对全局配置、针对具体类配置以及针对具体属性配置。他们生效的优先级顺序以此是:属性 > 类 > 全局。

全局配置

全局配置借助 com.fasterxml.jackson.databind.PropertyNamingStrategy实现

java
public class PropertyNamingStrategy  implements java.io.Serializable
{
    //会将 Java 属性名转换为小写,并且用下划线 _ 分隔单词。例如,idCard 会被转换为 id_card。  
    public static final PropertyNamingStrategy SNAKE_CASE = new SnakeCaseStrategy();

    //会将 Java 属性名的每个单词的首字母大写,其余字母小写,单词之间没有分隔符。例如,idCard 会被转换为 IdCard
    public static final PropertyNamingStrategy UPPER_CAMEL_CASE = new UpperCamelCaseStrategy();

    //会将 Java 属性名的第一个单词的首字母小写,其余单词的首字母大写,单词之间没有分隔符。这也是 Java 的标准命名规则。例如,idCard 会被保持不变
    public static final PropertyNamingStrategy LOWER_CAMEL_CASE = new PropertyNamingStrategy(); 
    
    //会将 Java 属性名转换为全小写,单词之间没有分隔符。例如,idCard 会被转换为 idcard
    public static final PropertyNamingStrategy LOWER_CASE = new LowerCaseStrategy();
    
    //会将 Java 属性名转换为小写,并且用短横线 - 分隔单词。例如,idCard 会被转换为 id-card。 
    public static final PropertyNamingStrategy KEBAB_CASE = new KebabCaseStrategy();
}

public static void main(String[] args) throws JsonProcessingException {
    Author author = new Author();
    author.setUsername("张三");
    author.setIdCard("31000000000000");
    author.setMobilePhone("13500000000")

    ObjectMapper mapper = new ObjectMapper()

    //使用PropertyNamingStrategy指定转化策略
    mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
}

针对具体类配置

针对类的配置同样是借助于 com.fasterxml.jackson.databind.PropertyNamingStrategy。区别是需要在类上使用 @JsonNaming注解

java
@JsonNaming(PropertyNamingStrategy.KebabCaseStrategy.class)
//@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)
//@JsonNaming(PropertyNamingStrategy.LowerCaseStrategy.class)
//@JsonNaming(PropertyNamingStrategy.KebabCaseStrategy.class)
// ...
public class Author {

}

public static void main(String[] args) throws JsonProcessingException {
    Author author = new Author();
    author.setUsername("张三");
    author.setIdCard("31000000000000");
    author.setMobilePhone("13500000000")

    ObjectMapper mapper = new ObjectMapper()

    // 优先级小于 @JsonNaming, 这里不会生效
    mapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE);

    System.out.println(mapper.writeValueAsString(author));
}

针对具体属性

java
@Getter
@Setter
@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class) // 优先级顺序小于 @JsonProperty
public class Author {

    private String username; // @JsonNaming 只会针对该属性生效

    @JsonProperty("id_card")
    private String idCard;

    @JsonProperty("mobile-phone")
    private String mobilePhone;
}