您好,登錄后才能下訂單哦!
這篇文章主要講解了“SpringBoot JSON全局日期格式轉換器如何實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“SpringBoot JSON全局日期格式轉換器如何實現”吧!
前臺有日期字符串的數據,提交到后臺。后臺實體類使用Date屬性接收。
日期字符串有多種格式,需要用一個轉換器將合法的日期字符串格式轉換為Date類型。
當前臺的提交數據的Content-Type
為application/json;charset=utf-8
,后臺使用@RequestBody
來接收數據的時候,使用此轉換方式。
用來標記日期字符串所對應的正則表達式
import java.lang.annotation.*; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) public @interface DatePattern { String value(); }
指定所有支持的日期格式
public final class DateFormatPart { @DatePattern("^\\d{4}$") public static final String YYYY = "yyyy"; @DatePattern("^\\d{4}\\d{2}$") public static final String YYYYMM = "yyyyMM"; @DatePattern("^\\d{4}/\\d{2}$") public static final String YYYYMM_SLASH = "yyyy/MM"; @DatePattern("^\\d{4}\\d{1,2}\\d{1,2}$") public static final String YYYYMMDD = "yyyyMMdd"; @DatePattern("^\\d{4}/\\d{2}/\\d{2}$") public static final String YYYYMMDD_SLASH = "yyyy/MM/dd"; @DatePattern("[0-9]+\\u5e74[0-9]+\\u6708[0-9]+\\u65e5$") public static final String YYYYMMDD_JP = "yyyy年MM月dd日"; @DatePattern("^\\d{4}\\d{1,2}\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}$") public static final String YYYYMMDD_HHMMSS = "yyyyMMdd HH:mm:ss"; @DatePattern("^\\d{4}/\\d{2}/\\d{2} \\d{1,2}:\\d{1,2}:\\d{1,2}$") public static final String YYYYMMDD_HHMMSS_SLASH = "yyyy/MM/dd HH:mm:ss"; }
從日期格式定數類中獲取所有的屬性值和該屬性上所標記的正則注解,通過反射來映射為map。
如果有需要增刪的日期格式的話,只需要修改日期格式定數即可,便于維護。
import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import java.lang.reflect.Field; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public final class DateUtil { // 日期格式 <==> 正則的map,使用LinkedHashMap可以避免按照順序匹配正則表達式 private static final Map<String, String> datePatternMap = new LinkedHashMap<>(); // 日期格式List private static final List<String> dateFormatList = new ArrayList<>(); // 使用靜態代碼塊,可以保證只初始化一次 static { Class<DateFormatPart> dateFormatClass = DateFormatPart.class; // 獲取所有的屬性 Field[] fields = dateFormatClass.getFields(); for (Field field : fields) { // 獲取屬性上的注解 DatePattern annotation = field.getAnnotation(DatePattern.class); if (ObjectUtils.isEmpty(annotation)) { continue; } // 強制讓屬性可以訪問 ReflectionUtils.makeAccessible(field); // 日期格式化字符串 String dateFormatStr = ""; try { // 獲取當前屬性所對應的屬性值 dateFormatStr = (String)field.get(dateFormatClass); } catch (IllegalAccessException e) { e.printStackTrace(); } dateFormatList.add(dateFormatStr); // 將該屬性的屬性值和屬性上的正則表達式放到map中 datePatternMap.put(dateFormatStr, annotation.value()); } } // 用所有可能支持的格式將日期字符串轉換為Date格式 public static Date formatDateStrToDateAllFormat(String dateStr) { if (ObjectUtils.isEmpty(dateStr)) { return null; } try { for (Map.Entry<String, String> mapEntry : datePatternMap.entrySet()) { // 如果當前日期字符串不符合當前正則的話 if (!dateStr.matches(mapEntry.getValue())) { continue; } return DateUtil.formatStringToDate(dateStr, mapEntry.getKey()); } } catch (ParseException e) { return null; } return null; } // 通過指定的格式將日期字符串轉換為Date類型 public static Date formatStringToDate(String dateStr, String format) throws ParseException { if (ObjectUtils.isEmpty(dateStr) || !dateFormatList.contains(format)) { return null; } SimpleDateFormat time = new SimpleDateFormat(format); return time.parse(dateStr); } }
該方式的要點是通過繼承DateDeserializer
類,然后重寫_parseDate
方法實現轉換功能
自定義的GlobalDateDeserializer
類需要添加到自定義的SimpleModule
模塊中,然后將模塊添加到ObjectMapper
中,通過jackson
來實現轉換。
通過設置ObjectMapper
對象的setDateFormat
方法來實現后臺數據返回到前臺時的Date轉String的默認格式。
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.json.PackageVersion; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.deser.std.DateDeserializers.DateDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; @Configuration public class CustomConfig { /* * 自定義的全局的日期轉換解析類,需要繼承jackson包中的DateDeserializer * 因為此類不會在別的地方使用了,因此直接使用內部類聚合到自定義的配置文件中 */ private static final class GlobalDateDeserializer extends DateDeserializer { @Override protected Date _parseDate(JsonParser jp, DeserializationContext context) throws IOException { return DateUtil.formatDateStrToDateAllFormat(jp.getText()); } } @Bean("objectMapper") @Primary @ConditionalOnMissingBean public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { // 創建jackson對象 ObjectMapper jackson = builder.createXmlMapper(false).build(); /* * DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES * 在進行序列化或者反序列化的時候, * JSON字符串中有一個字段,但是我們的對象沒有這個字段的時候,該怎么處理 * 設置為true的時候,會拋出異常 * 設置為false,忽略異常繼續處理 */ jackson.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 禁用默認的「yyyy-MM-dd'T'HH:mm:ss.SSS」UTC類型 jackson.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); /* * 設置序列化時的默認格式,即后臺返回數據到前臺的時候, * Date類型數據需要轉換為的字符串格式 * 如果不進行指定的話,默認使用 yyyy-MM-dd'T'HH:mm:ss.SSS 格式 */ DateFormat dateFormat = new SimpleDateFormat(DateFormatPart.YYYYMMDD_HHMMSS_SLASH); jackson.setDateFormat(dateFormat); // 創建一個模塊,指定該模塊是用來解析 Date.class 類型數據的 SimpleModule newModule = new SimpleModule("GlobalDateDeserializer", PackageVersion.VERSION); // 將我們創建的全局日期轉換類添加到模塊中,指定轉換Date類型 newModule.addDeserializer(Date.class, new CustomConfig.GlobalDateDeserializer()); // 將該模塊添加到jackson中 jackson.registerModule(newModule); return jackson; } }
parse
方法用來將日期字符串轉換為Date(前臺向后臺傳數據)
forma
t方法用來將Date格式的數據轉換為指定格式的字符串(后臺向前臺傳數據)。
import java.text.FieldPosition; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; import com.fasterxml.jackson.databind.util.StdDateFormat; public class GlobalJsonDateConvert extends StdDateFormat { // 靜態初始化final,共享 public static final GlobalJsonDateConvert instance = new GlobalJsonDateConvert(); // 日期字符串解析為日期 @Override public Date parse(String dateStr, ParsePosition pos) { return getDate(dateStr); } @Override public Date parse(String dateStr) { return getDate(dateStr); } // 使用自定義的日期轉換工具類將所有可能支持的日期字符串轉換為Date格式 private Date getDate(String dateStr) { return DateUtil.formatDateStrToDateAllFormat(dateStr); } /* * 設置序列化時的默認格式,即后臺返回數據到前臺的時候, * Date類型數據需要轉換為的字符串格式 * 如果不進行指定的話,默認使用 yyyy-MM-dd'T'HH:mm:ss.SSS 格式 */ @Override public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition){ SimpleDateFormat sdf = new SimpleDateFormat(DateFormatPart.YYYYMMDD_HHMMSS_SLASH); return sdf.format(date, toAppendTo, fieldPosition); } @Override public GlobalJsonDateConvert clone() { super.clone(); return new GlobalJsonDateConvert(); } }
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @Configuration public class CustomConfig { // JSON格式 全局日期轉換器配置 @Bean public MappingJackson2HttpMessageConverter createMappingJackson2HttpMessageConverter() { /* * 通過MappingJackson2HttpMessageConverter得到的ObjectMapper, * 已經默認把 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 給關閉了 */ MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(); jacksonConverter.getObjectMapper().setDateFormat(GlobalJsonDateConvert.instance); return jacksonConverter; } }
通過Jackson2ObjectMapperBuilder創建ObjectMapper對象,然后將我們定義的轉換器GlobalJsonDateConvert
放到ObjectMapper對象中
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class CustomConfig { @Bean("objectMapper") @Primary @ConditionalOnMissingBean public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.build(); objectMapper.setDateFormat(GlobalJsonDateConvert.instance); return objectMapper; } }
將我們定義的轉換器GlobalJsonDateConvert
放到Jackson2ObjectMapperBuilder
對象中
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; @Configuration public class CustomConfig { @Bean public Jackson2ObjectMapperBuilder objectMapper() { Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder(); jackson2ObjectMapperBuilder.dateFormat(GlobalJsonDateConvert.instance); return jackson2ObjectMapperBuilder; } }
?前臺JS
// 向后臺傳輸的json數據 const jsonData = { // ????待處理的日期字符串數據 birthday: '2027年12月12日', nameAA: 'jiafeitian', hobby: '吃飯' }; $.ajax({ url: url, type: 'POST', // 對象轉換為json字符串 data: JSON.stringify(jsonData), contentType: "application/json;charset=utf-8", success: function (data, status, xhr) { console.log(data); } });
?后臺Form
import lombok.Data; import java.util.Date; @Data public class Test15Form { private String name; private String hobby; private String address; // 用來接收的Date類型的數據 private Date birthday; }
可以看到前臺提交的日期字符串被轉換為Date格式了
感謝各位的閱讀,以上就是“SpringBoot JSON全局日期格式轉換器如何實現”的內容了,經過本文的學習后,相信大家對SpringBoot JSON全局日期格式轉換器如何實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。