在开发中经常会遇到前端传时间字符串,后端又是时间对象。然后就转来转去非常麻烦。接的时候string到date.回去的时候date->string.
你也许会想到一个优雅的方式。
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
但是我们还可以更优雅点,和这个注解配合。就是使用一个转换器
package com.lar.config;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
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 lombok.SneakyThrows;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
@Configuration
public class TimeFormatConvert {
@Bean
@Primary
public ObjectMapper objectMapper() {
// 序列化为时间字符串给前端,和前端时间字符串反序列化为日期对象
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(TimeFormat.DateTime)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(TimeFormat.Date)));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(TimeFormat.Time)));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(TimeFormat.DateTime)));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(TimeFormat.Date)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(TimeFormat.Time)));
javaTimeModule.addSerializer(Date.class, new DateSerializer());
javaTimeModule.addDeserializer(Date.class, new DateDeserializer());
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
public interface TimeFormat {
String DateTime = "yyyy-MM-dd HH:mm:ss";
String Date = "yyyy-MM-dd";
String Time = "HH:mm:ss";
}
public static class DateSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat(TimeFormat.DateTime);
formatter.setLenient(true);
formatter.setTimeZone(TimeZone.getDefault());
String formattedDate = formatter.format(date);
jsonGenerator.writeString(formattedDate);
}
}
public static class DateDeserializer extends JsonDeserializer<Date> {
@SneakyThrows
@Override
public Date deserialize(JsonParser p, DeserializationContext deserializationContext) {
if (p.getText() == null || "".equals(p.getText().trim())) {
return null;
}
SimpleDateFormat formatter = new SimpleDateFormat(TimeFormat.DateTime);
formatter.setLenient(true);
formatter.setTimeZone(TimeZone.getDefault());
if(p.getText().length()<=10){
formatter = new SimpleDateFormat(TimeFormat.Date);
if (p.getText().charAt(4) != '-') {
formatter = new SimpleDateFormat(TimeFormat.Time);
}
}
return formatter.parse(p.getText());
}
}
}
后端model还是时间对象接收
上面效果实现了传是字符串回来还是字符串。这样大部分场景你代码都不用手动改。最后建议用新的api.localdate,更加好用.这可是我研究了好久的。所有时间除了date这块比较麻烦。默认只处理全部格式的序列化,鬼知道前端要啥奇奇怪怪的格式。然后不会有人只传时分秒用date对象吧。不会吧。。