1. 程式人生 > 其它 >Springboot全域性日期時間格式處理

Springboot全域性日期時間格式處理

大傢伙在日常開發中可能都遇到過,前端傳遞的時間字串,後臺如果用日期接收(Date或者jdk8的Local日期)接收,經mvc接收後就報錯了,先解析原因:

1. get請求和post表單請求中如果含有時間字串,則spring底層是用的ParameterConversionService這個引數解析器去轉換的
2. post的json請求時, spring底層預設用的是Jackson的HttpMessagConverter去做的序列化

so, 根據不同請求方式,做不同的日期時間格式配置處理:

* 1. GET請求及POST表單請求(RequestParam和PathVariable引數):
* -- 配置Converter<String, T>轉換器實現引數轉換, 該轉換器bean會注入到spring mvc的引數解析器中(ParameterConversionService) * * 2. POST-application/json請求(RequestBody引數) * -- 配置ObjectMapper(這個玩意兒會注入到Jackson的HttpMessagConverter裡面,即MappingJackson2HttpMessageConverter中)來實現Json格式資料的序列化和反序列化

詳細配置:

@Configuration
public class
DateHandlerConfig { /** * 預設日期時間格式 */ private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; /** * 預設日期格式 */ private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; /** * 預設時間格式 */ private static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
/** * Date轉換器 * 採用hutool的日期解析工具類Dateutil可以匹配任意格式日期字串 */ @Bean public Converter<String, Date> dateConverter() { return new Converter<String, Date>() { @Override public Date convert(String source) { return DateUtil.parse(source.trim()); } }; } /** * LocalDate轉換器 */ @Bean public Converter<String, LocalDate> localDateConverter() { return new Converter<String, LocalDate>() { @Override public LocalDate convert(String source) { return LocalDate.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)); } }; } /** * LocalTime轉換器 */ @Bean public Converter<String, LocalTime> localTimeConverter() { return new Converter<String, LocalTime>() { @Override public LocalTime convert(String source) { return LocalTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)); } }; } /** * LocalDateTime轉換器 */ @Bean public Converter<String, LocalDateTime> localDateTimeConverter() { return new Converter<String, LocalDateTime>() { @Override public LocalDateTime convert(String source) { return LocalDateTime.parse(source, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)); } }; } /** * Json序列化和反序列化轉換器 */ @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); //java8日期 Local系列序列化和反序列化模組 JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))); javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))); javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))); javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))); javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); objectMapper.registerModule(new ParameterNamesModule()).registerModule(new Jdk8Module()).registerModule(javaTimeModule); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); // 忽略json字串中不識別的屬性 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略無法轉換的物件 objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); // PrettyPrinter 格式化輸出 objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true); // NULL不參與序列化 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 指定時區 objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8:00")); /** * Date日期型別字串全域性處理, 預設格式為:yyyy-MM-dd HH:mm:ss * 區域性處理某個Date屬性欄位接收或返回日期格式yyyy-MM-dd, 可採用@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")註解標註該屬性 */ objectMapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT)); return objectMapper; } }

注意點:

* 區域性日期格式化處理:
     * --以上ObjectMapper配置預設json請求中的Date會轉化成yyyy-MM-dd HH:mm:ss格式
     * --如果需要接收或返回是yyyy-MM-dd格式, 採用@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")註解單獨標註該實體類屬性即可

通過以上配置.可解決的問題:

1. 支援請求入參String轉Date, 支援get, post(表單 或 json)請求

2. 支援返回資料為Date型別的轉為日期時間String

3. 支援Java8日期API, 如: LocalTime, LocalDate, LocalDateTime

4. 支援區域性修改日期時間的接收和返回格式

 

最後,這篇博文寫的不錯,強烈推薦: https://juejin.cn/post/6844904083388792839