问题:
1.想返回指定的格式,比如时间戳或者指定的字符串格式。
2.想接收指定的格式,比如时间戳或者字符串(默认要带T才行,可以设置成不带T)。
3.想全局设置。
原理:
重新定义LocalDateTime的序列化方式和反序列化方式。
序列化: 把对象转化为字节。 (指定返回格式)
反序列化: 把字节转化为对象。(接收指定格式)
LocalDateTime序列化与反序列化的核心类:
com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer的deserialize方法
com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer的serialize方法
ObjectMapper 给 指定类 设置 序列化方式
文档:
查看源码
步骤:
1.创建LocalDateTimeSerializer类(为了返回时间戳)
2.重定义mapperObject的Bean.
1 创建LocalDateTimeSerializer类(自定义序列化方式,返回时间戳):
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
/**
* 处理localdatetime 不返回时间戳的问题
*
* @author dripy
* @date 2019/12/17 20:08
*/
public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime local DateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeNumber(local DateTime.toInstant(ZoneOffset.of("+8" )).toEpochMilli());
}
}
2 重定义mapperObject的Bean:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @author dripy
* @date 2019/12/17 20:08
*/
@Configuration
public class Config {
/**
* 设置localdatetime的序列化与反序列化的方式
*
* @return
*/
@Bean(name = "mapperObject" )
public ObjectMapper getObjectMapper () {
ObjectMapper om = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
// "下面两个根据实际情况选择 看要返回什么格式"
// "返回时间戳 注意这里的LocalDateTimeSerializer是上面自己实现的一个"
// javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
// "返回指定字符串格式 这里的LocalDateTimeSerializer是com.fasterxml.jackson.datatype.jsr310.ser下的"
javaTimeModule.addSerializer(LocalDateTime.class, new com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" )));
// 这个反序列化。接受前端传来的格式
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" )));
// 这两个得加上。不然他俩默认返回了List结构
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd" )));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss" )));
om.registerModule(javaTimeModule);
return om;
}
}
补充:
核心类:
com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer的deserialize方法
com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer的serialize方法
可尝试在这两个方法中打上断点。查看请求与返回的时候使用的是什么格式的DateTimeFormatter
尽然知道了原理。就知道怎么改变了。
1.接收yyyy-MM-dd HH:mm:ss格式
2.接收时间戳格式
3.返回yyyy-MM-dd HH:mm:ss格式
4.返回时间戳格式
补充2:
当实现了implements WebMvcConfigurer的时候,必须手动设置进去。
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(getObjectMapper());
converters.add(converter);
}
// 手动加入类型序列化。
public ObjectMapper getObjectMapper () {
ObjectMapper om = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd" )));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss" )));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" )));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd" )));
om.registerModule(javaTimeModule);
return om;
}
补充3: 当用LocalDateTime用作get请求传参的时候
get请求的话, 不走反序列化,而是直接String的值塞给对应的类型,默认是没有转换器,会抛出异常。
配置了转换器后,当用LocalDateTime接收get请求参数的时候,就会进入这个转换器中
/**
* get方式的参数 定义String与对应类型的转换方式
*
* @return
*/
@Bean
public Converter<String, LocalDateTime> LocalDateTimeConvert () {
return new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(String source ) {
if (StringUtils.isEmpty(source )) {
return null;
}
return LocalDateTime.parse(source , DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" ));
}
};
}
补充4: spirngboot 默认使用的序列化方式就是 jackson
重点就是 ObjectMapper对象。