spring-cloud-feign 对 Java8 日期的序列化
前言
如果用过spring-cloud的同学应该知道,feign接口默认底层默认是http来进行请求的,一般spring的web项目都是通过Jackson来进行序列化跟反序列化,在对象传输的时候,如果对象里面的时间类型是Java8的时间类,可能会反序列化失败,因此,我们需要配置一下针对Java8提供的时间类进行定制的序列化,因此,我们默认使用LocalDateTime示例,LocalDate跟LocalTime实际上也是一样的
引入JSR310依赖
在项目内,我们引用下依赖
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.8.11</version>
</dependency>
使用JSR310默认配置
默认的情况下,JSR310给我们提供了转换成字符串的序列化/反序列化类,分别是LocalDateTimeSerializer
/LocalDateTimeDeserializer
,我们可以使用已经有的实现,来进行序列化
接着我们通过Spring的自动装配,返回一个Bean
@Configuration
public class JacksonSerializerConfiguration{
@Bean
public ObjectMapper buildObjectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.addDeserializer(LocalDateTime.class,new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}
使用自定义配置
当然,我们不想使用默认的,我们也可以自定义配置,继承JsonSerializer类,实现抽象方法,或者继承JSR310的InstantSerializer类,然后重写构造器,作为示例,我们就继承JsonSerializer作为演示
例如,我们想序列化LocalDateTime到秒的时间戳,代码如下
public class InstantSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
gen.writeNumber(DateUtils.toSecond(value));
}
}
public class InstantDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext txt) throws IOException, JsonProcessingException {
return Instant.ofEpochSecond(p.getLongValue()).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
}
@Configuration
public class JacksonSerializerConfiguration{
@Bean
public ObjectMapper buildObjectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new InstantSerializer())
.addDeserializer(LocalDateTime.class,new InstantDeserializer());
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}
总结
JSR310给我们很多的基础实现,简单的可以使用基础的实现,如果要自定义的话,通过继承jackson提供的抽象类,自己进行实现,两者实现上差不多,不过通过继承更灵活,更可控,使用jsr310更方便,具体的使用就仁者见仁智者见智了