@JsonSerialize @JsonDeserialize @JsonFormat 三个注解的区别及一般用法

发布时间 2023-09-14 15:05:48作者: 品书读茶

区别

  • @JsonSerialize:该注解用于指定在将Java对象序列化为JSON字符串时使用的序列化器。可以将其应用于字段、方法或类级别。通过@JsonSerialize注解,可以自定义序列化过程,例如将日期格式化为特定的字符串、将枚举类型序列化为其名称而不是值等。
  • @JsonDeserialize:该注解用于指定在将JSON字符串反序列化为Java对象时使用的反序列化器。可以将其应用于字段、方法或类级别。通过@JsonDeserialize注解,可以自定义反序列化过程,例如将特定字符串转换为日期对象、将JSON中的特定字段映射到Java对象的不同属性等。
  • @JsonFormat:该注解用于指定在序列化和反序列化过程中应用的格式化规则。可以将其应用于字段、方法或类级别。通过@JsonFormat注解,可以定义日期、时间、数字等类型的格式,例如指定日期格式、指定数字的小数位数、指定枚举类型的序列化方式等。
    总结起来,@JsonSerialize用于自定义序列化过程,@JsonDeserialize用于自定义反序列化过程,@JsonFormat用于指定序列化和反序列化的格式化规则。它们可以根据需求灵活地控制对象的序列化和反序列化行为。

@JsonSerialize用法

@JsonSerialize可以在对象序列化时执行自定义的代码,我们利用这个特性可以针对对象某个属性进行特性的处理。用法例子以LocalDateTime格式化

  • 属性
@JsonSerialize(using = LocalDateTimeFormmatSerializa.class)
private LocalDateTime planInDate;
  • 序列化器
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeFormmatSerializa extends JsonSerializer<LocalDateTime> {

    @Override
    public void serialize(LocalDateTime param, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if (param != null) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒");
            jsonGenerator.writeString(param.format(formatter));
        }
    }
}

@JsonDeserialize用法

@JsonDeserialize可以在对象反序列化时执行自定义的代码,我们利用这个特性可以针对对象某个属性进行特性的处理。将特定格式的日期时间反序列化成LocalDateTime对象

  • 属性
@JsonDeserialize(using = LocalDateTimeFormmatDeserializa.class)
private LocalDateTime planInDate;
  • 反序列化器
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDateTimeFormmatDeserializa extends JsonDeserializer<LocalDateTime> {
    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        JsonNode node = p.getCodec().readTree(p);
        // 只所以是用"yyyy-MM-dd'T'HH:mm:ss"这个格式解析成对象,是因为json字符串字段格式这样的
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        LocalDateTime parse = LocalDateTime.parse(node.asText(), formatter);
        return parse;
    }
}

@JsonFormat用法

@JsonFormat当用这个注解使用在对象属性上去格式化时间时,可以简单理解为@JsonSerialize@JsonDeserialize两个注解加和,对象序列化和反序列化时都执行。
我们也可以在getter 和 setter方法上去使用@JsonFormat,这样可以在对象序列化和反序列化拆开使用。如下面例子:

@JsonFormat(pattern = "yyyy年MM月dd日HH时mm分ss秒",timezone="GMT+8")
public LocalDateTime getPlanInDate() {
    return planInDate;
}

@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss",timezone="GMT+8")
public void setPlanInDate(LocalDateTime planInDate) {
    this.planInDate = planInDate;
}

对象序列化和反序列化拆开使用场景

在分布式架构,难免存在工程A中封装工程B中的接口,我们想在工程A中接收的参数对象和controller中返回的参数对象使用一个,这时就可以对象序列化和反序列化拆开使用。
比如我接收到的时间格式为'yyyy-MM-dd HH:mm:ss',但是我想返回的时间格式为'yyyy年MM月dd日HH时mm分ss秒',这样一个注解就搞定了,不用再在service中用代码单独处理

以上的用法只是奇技淫巧,大多数情况下用不到,只是在特定场景才会用到,但是多了解一些总是好的