SpringBoot
日期格式化處理(單獨與全局)
包括單獨,與全局
1. 單獨配置
1.1 使用Springboot
提供註解方式
springboot默認提供,在需要的字段上使用
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
這個方式每個字段都需要加有點過於麻煩。
1.2. 使用Spring
自帶註解
@DateTimeFormat(pattern = "yyyy-MM-dd")
這個方式每個字段都需要加有點過於麻煩。
2. 全局配置
2.1 在配置文件上配置
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
-
支持(content-type=application/json)請求中格式爲yyyy-MM-dd HH:mm:ss的字符串,後臺用@RequestBody接收,及返回值date轉爲yyyy-MM-dd HH:mm:ss格式string;
-
不支持(content-type=application/json)請求中yyyy-MM-dd等類型的字符串轉爲date;
-
不支持
java8
日期api
。
2.2 使用配置類方式
適合前後端都是
json
格式交互。只需要用
@Configuration
定義一個配置類,注入兩個Bean
即可完成全局日期響應格式化處理。
@Configuration
public class LocalDateTimeSerializerConfig {
/** 注入配置文件格式化的格式
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;*/
private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
/**
* 註冊響應json格式的LocalDateTime日期格式序列化器,指定格式
*
* @return LocalDateTimeSerializer
* @author: zhihao
* @date: 2020/4/14
*/
@Bean
public LocalDateTimeSerializer localDateTimeSerializer() {
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));
}
/**
* 註冊json請求方式的LocalDateTime反序列化器,指定格式
*
* @return LocalDateTimeDeserializer
* @author: zhihao
* @date: 2020/4/14
*/
@Bean
public LocalDateTimeDeserializer localDateTimeDeserializer() {
return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));
}
/**
* 格式化日期類型,響應對應格式化日期字符串
*
* @return Jackson2ObjectMapperBuilderCustomizer
* @author: zhihao
* @date: 2020/4/14
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> {
//返回json格式,前端序列化爲字符串
builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
//從json對象日期字符串反序列化爲日期對象
builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());
};
}
}
上面方式如果需要其他格式,那就需要配合
@JsonFormat
註解使用,在特定的字段屬性添加@JsonFormat
註解即可,因爲@JsonFormat
註解優先級比較高,會以@JsonFormat
註解標註的時間格式爲主。
2.3.使用Jackson
解決
JSON
請求的序列化和響應Json
的反序列化, 適合前後端都是json
格式交互。根據官方文檔 Custom JSON Serializers and Deserializers ,想要接管Jackson的JSON的序列化和反序列化,只需通過註解
@JsonComponent
來聲明其靜態內部類即可。
首先根據項目要求提供自定義的日期序列化器和反序列化器,其中包括:
-
DateJsonSerializer extends JsonSerializer
表示將LocalDateTime
格式化爲日期字符串。 -
DateJsonDeserializer extends JsonDeserializer
表示將日期字符串解析爲LocalDateTime
日期。使用註解
@JsonComponent
是直接處理String和LocalDateTime的相互轉換的,所以要注意空串問題。
@JsonComponent
public class DateFormatConfig {
/**
* 響應json日期格式化
*/
public static class DateJsonSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
jsonGenerator.writeString(localDateTime.format(formatter));
}
}
/**
* 解析json請求日期字符串
*/
public static class DateJsonDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
return LocalDateTime.parse(jsonParser.getText());
}
}
}
2.4 GET請求及POST表單日期時間字符串格式轉換
這種情況要和時間作爲Json字符串時區別對待,因爲前端json轉後端
entity
底層使用的是Json序列化Jackson工具(HttpMessageConverter<T>
);而時間字符串作爲普通請求參數傳入時,轉換用的是Converter<S, T>
,兩者在處理方式上是有區別。非json請求的轉換
使用自定義參數轉換器(Converter)
實現 org.springframework.core.convert.converter.Converter
,自定義參數轉換器,如下:
@Configuration
public class DateConverterConfig {
private static final String YYYY_MM_DD = "yyyy-MM-dd";
private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
/**
* 自定義類型轉換,HTTP請求日期字符串轉換日期類型,
* 相當於以前設置進 ConversionServiceFactoryBean
*
* @return Converter<java.lang.String,java.util.Date>
* @author: zhihao
* @date: 2020/4/14
*/
@Bean
public Converter<String, LocalDateTime> localDateTimeConverter() {
return new Converter<String, LocalDateTime>() {
@Override
public LocalDateTime convert(String source) {
try {
return parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
throw new RuntimeException("日期解析錯誤");
}
};
}
/**
* 根據字符串進行解析,將Date轉LocalDateTime
*
* @param source 日期字符串
* @return java.time.LocalDateTime
* @author: zhihao
* @date: 2020/4/14
*/
public LocalDateTime parse(String source) throws ParseException {
if (StringUtils.isBlank(source)) {
return null;
}
DateFormat format;
source = source.trim();
//判斷是否yyyy-MM-dd格式
if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")){
format = new SimpleDateFormat(YYYY_MM_DD);
Date date = format.parse(source);
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
//判斷是否yyyy-MM-dd HH:mm:ss格式
}else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")){
format = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
Date date = format.parse(source);
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}else {
throw new IllegalArgumentException("Invalid false value " + source);
}
}
}
點評:以上兩個bean會注入到spring mvc的參數解析器(好像叫做ParameterConversionService
),當傳入的字符串要轉爲LocalDateTime類時,spring會調用該Converter對這個入參進行轉換。
參考了:
https://www.jianshu.com/p/f4654d251104
https://segmentfault.com/a/1190000022355979