我的预想是支持多种格式,还支持时间戳,直接上代码(要用 Fastjson 看文末参考)
时间配置类:
import org.csaarg.util.DateUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
/**
* Spring 中使用 LocalDateTime、LocalDate 等参数作为入参:https://www.jianshu.com/p/b52db905f020
*
* @author duanluan
*/
@Configuration
public class DateConfig {
/**
* 默认日期时间格式
*/
public static final String DEFAULT_DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_NEW_DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
// /**
// * 默认日期格式
// */
// public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
// /**
// * 默认时间格式
// */
// public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss";
/**
* 使用 RequestParam 或 PathVariable 注解时 String 转 LocalDate
*/
@Bean
public Converter<String, LocalDate> localDateConverter() {
return new Converter<String, LocalDate>() {
@Override
public LocalDate convert(String source) {
return DateUtils.parseLocalDate(source);
}
};
}
/**
* 使用 RequestParam 或 PathVariable 注解时 String 转 LocalDateTime
*/
@Bean
public Converter<String, LocalDateTime> localDateTimeConverter() {
return new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(String source) {
return DateUtils.parseLocalDateTime(source);
}
};
}
/**
* Json 序列化和反序列化转换器,用于转换 Post 请求体中的 json 以及将我们的对象序列化为返回响应的 json
*/
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
// LocalDateTime 系列序列化和反序列化模块,继承自 jsr310,我们在这里修改了日期格式
JavaTimeModule javaTimeModule = new JavaTimeModule();
// javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateUtils.getDefaultFormatter(null, DateUtils.PATTERN_UUUU_MM_DD)));
// javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_PATTERN)));
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateUtils.getDefaultFormatter(null, DateUtils.PATTERN_UUUU_MM_DD_HH_MM_SS)));
// javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN)));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateUtils.getDefaultFormatter(null, DateUtils.PATTERN_HH_MM_SS)));
javaTimeModule.addDeserializer(LocalDate.class, new JsonDeserializer<LocalDate>() {
@Override
public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
return DateUtils.parseLocalDate(jsonParser.getText());
}
});
javaTimeModule.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
return DateUtils.parseLocalDateTime(jsonParser.getText());
}
});
// javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_PATTERN)));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateUtils.getDefaultFormatter(null, DateUtils.PATTERN_HH_MM_SS)));
// 序列化:Date 转字符串
javaTimeModule.addSerializer(Date.class, new JsonSerializer<Date>() {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_TIME_PATTERN);
jsonGenerator.writeString(dateFormat.format(date));
}
});
// 反序列化:字符串转 Date
javaTimeModule.addDeserializer(Date.class, new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String source = jsonParser.getText();
SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_TIME_PATTERN);
try {
return dateFormat.parse(source);
} catch (ParseException e) {
dateFormat = new SimpleDateFormat(DEFAULT_NEW_DATE_TIME_PATTERN);
try {
return dateFormat.parse(source);
} catch (ParseException parseException) {
throw new RuntimeException(e);
}
}
}
});
objectMapper.registerModule(javaTimeModule);
return objectMapper;
}
}
Spring MVC 配置:
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Spring MVC 配置
*
* @author duanluan
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
// 时间配置
@Autowired
private DateConfig dateConfig;
/**
* Jackson 转换
*
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// 根据时间配置获取 ObjectMapper
ObjectMapper objectMapper = dateConfig.objectMapper();
// 忽略前端传递过来但是 @RequestBody 注解的对象中没有的参数(https://www.jianshu.com/p/83a170baf10c),相当于在实体类中添加 @JsonIgnoreProperties(ignoreUnknown = true)
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
converter.setObjectMapper(objectMapper);
return converter;
}
}
相关类
Java 8 时间工具类:DateUtils
注意
在 DateConfig 中定义了一个 ObjectMapper,有其他地方需要配置这个对象的时候,比如 MappingJackson2HttpMessageConverter,需要 @Autowired DateConfig 后用 objectMapper() 方法。
评论区