Jackson 反序列化 “yyyy-MM-dd” = > LocalDateTime
标准格式 yyyy-MM-dd’T’HH:mm:ss
全局配置
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.gientech.lcds.generator.commons.biz.convert.SystemConvertor;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
/**
* web配置
*
* desc: LONG转STRING; 解决web返回的json数据中long类型精度丢失问题。
*/
@Configuration
public class WebConfiguration {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return jacksonObjectMapperBuilder ->
jacksonObjectMapperBuilder
.serializerByType(Long.class, ToStringSerializer.instance)
.serializerByType(Long.TYPE, ToStringSerializer.instance)
.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.serializerByType(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.serializerByType(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")))
.deserializerByType(LocalDateTime.class, new LocalDateTimeTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.deserializerByType(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.deserializerByType(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
}
}
前端传值格式为 yyyy-MM-dd
选择自定义反序列化器
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.datatype.jsr310.deser.JSR310DateTimeDeserializerBase;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
@Slf4j
public class CustomLocalDateTimeDeserializer extends JSR310DateTimeDeserializerBase<LocalDateTime> {
private static final long serialVersionUID = 13355608L;
private static final DateTimeFormatter DEFAULT_FORMATTER;
public static final CustomLocalDateTimeDeserializer INSTANCE;
static {
DEFAULT_FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
INSTANCE = new CustomLocalDateTimeDeserializer();
}
protected CustomLocalDateTimeDeserializer(){
this(DEFAULT_FORMATTER);
}
public CustomLocalDateTimeDeserializer(DateTimeFormatter formatter){
super(LocalDateTime.class, formatter);
}
protected CustomLocalDateTimeDeserializer(CustomLocalDateTimeDeserializer base, Boolean leniency) {
super(base, leniency);
}
@Override
protected JSR310DateTimeDeserializerBase<LocalDateTime> withDateFormat(DateTimeFormatter formater) {
return new CustomLocalDateTimeDeserializer(formater);
}
@Override
protected JSR310DateTimeDeserializerBase<LocalDateTime> withLeniency(Boolean aBoolean) {
return new CustomLocalDateTimeDeserializer(this,aBoolean);
}
@Override
protected JSR310DateTimeDeserializerBase<LocalDateTime> withShape(JsonFormat.Shape shape) {
return this;
}
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
String date = jsonParser.getText();
try {
final DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd[['T'HH][:mm][:ss]]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.parseDefaulting(ChronoField.MILLI_OF_SECOND, 0)
.toFormatter();
final LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
return localDateTime;
} catch (Exception ex) {
log.debug("Error while parsing date: {} ", date, ex);
throw new RuntimeException("Cannot Parse Date");
}
}
}
CustomLocalDateTimeDeserializer
是我仿照LocalDateTimeDeserializer
写的 , 关键方法就是deserialize()
, 其中内容主要援引了rxliuli的博客- 不想要全局配置可以参照
StackOverflow的回答
后记
- 标准格式传值的话
LocalDateTimeDeserializer
就可以解析 , 但是当格式是其他格式的时候解析会报错 , 具体解析方法参见LocalDateTimeDeserializer.deserialize()
;