解決SpringMVC 返回Java8 時(shí)間JSON數(shù)據(jù)的格式化問題處理
有時(shí)在Spring MVC中返回JSON格式的response的時(shí)候會(huì)使用@ResponseBody注解,不過在處理java8中時(shí)間的時(shí)候會(huì)很麻煩,一般我們使用的HTTPMessageConverter是MappingJackson2HttpMessageConverter,它默認(rèn)返回的時(shí)間格式是這種:
"startDate" : { "year" : 2010, "month" : "JANUARY", "dayOfMonth" : 1, "dayOfWeek" : "FRIDAY", "dayOfYear" : 1, "monthValue" : 1, "hour" : 2, "minute" : 2, "second" : 0, "nano" : 0, "chronology" : { "id" : "ISO", "calendarType" : "iso8601" } }
但是我們不會(huì)返回這種給前端使用,針對(duì)LocalDate想要返回的格式是2016-11-26,而LocalDateTime想要返回的格式是2016-11-26 21:04:34這樣的數(shù)據(jù)。通過項(xiàng)目研究并查閱相關(guān)資料,這里介紹下個(gè)人研究中實(shí)現(xiàn)的兩種方式。
解決方法一:
若是maven項(xiàng)目,在pom中引入下面的jar包:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.8.5</version> </dependency>
然后在你想要JSON化的POJO字段的get函數(shù)上加上一個(gè)@JsonSerializer注解,如下
import com.fasterxml.jackson.annotation.JsonFormat; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") public LocalDateTime getBirthday() { return this.loginTime; } @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") public LocalDateTime getLastLoginTime() { return this.loginTime; }
這種方式的優(yōu)點(diǎn)是可以針對(duì)具體域類型設(shè)置不同顯示方式,然而優(yōu)點(diǎn)也是缺點(diǎn),因?yàn)槊總€(gè)日期屬性都要手動(dòng)添加,實(shí)際中日期屬性又是普遍必備,并且需要額外引入jsr310的jar包。
解決方法二:
繼承ObjectMapper來實(shí)現(xiàn)返回json字符串。MappingJackson2HttpMessageConverter主要通過ObjectMapper來實(shí)現(xiàn)返回json字符串。這里我們編寫一個(gè)JsonUtil類,獲取ObjectMapper以針對(duì)java8中新的日期時(shí)間API,注冊相應(yīng)的JsonSerializer<T>。
/** * json處理工具類 * * */ @Component public class JsonUtil { private static final ObjectMapper mapper; public ObjectMapper getMapper() { return mapper; } static { mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(LocalDate.class, new LocalDateSerializer()); module.addSerializer(LocalTime.class, new LocalTimeSerializer()); module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer()); mapper.registerModule(module); } public static String toJson(Object obj) { try { return mapper.writeValueAsString(obj); } catch (Exception e) { throw new RuntimeException("轉(zhuǎn)換json字符失敗!"); } } public <T> T toObject(String json, Class<T> clazz) { try { return mapper.readValue(json, clazz); } catch (IOException e) { throw new RuntimeException("將json字符轉(zhuǎn)換為對(duì)象時(shí)失敗!"); } } } class LocalDateSerializer extends JsonSerializer<LocalDate> { private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); @Override public void serialize(LocalDate value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(dateFormatter.format(value)); } } class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> { private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public void serialize(LocalDateTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(dateTimeFormatter.format(value)); } } class LocalTimeSerializer extends JsonSerializer<LocalTime> { private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); @Override public void serialize(LocalTime value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(timeFormatter.format(value)); } }
然后在springmvc的配置文件中,再將<mvc:annotation-driven/>改為以下配置,配置一個(gè)新的json轉(zhuǎn)換器,將它的ObjectMapper對(duì)象設(shè)置為JsonUtil中的objectMapper對(duì)象,此轉(zhuǎn)換器比spring內(nèi)置的json轉(zhuǎn)換器優(yōu)先級(jí)更高,所以與json有關(guān)的轉(zhuǎn)換,spring會(huì)優(yōu)先使用它。
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper" value="#{jsonUtil.mapper}" /> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
然后java8中的幾種日期和時(shí)間類型就可以正常友好的顯示了。優(yōu)點(diǎn)是全局統(tǒng)一管理日期和時(shí)間等類型,缺點(diǎn)對(duì)pojo中的某個(gè)域做特殊處理。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Kotlin與java8的SAM轉(zhuǎn)換對(duì)比(進(jìn)階)
這篇文章主要介紹了Kotlin與java8的SAM轉(zhuǎn)換對(duì)比,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05JavaEE實(shí)現(xiàn)前后臺(tái)交互的文件上傳與下載
這篇文章主要介紹了JavaEE實(shí)現(xiàn)前后臺(tái)交互的文件上傳與下載,分享相關(guān)技術(shù),實(shí)現(xiàn)文件上傳下載功能,需要的朋友可以參考下2015-11-11Java Web實(shí)現(xiàn)添加定時(shí)任務(wù)的方法示例
這篇文章主要介紹了Java Web實(shí)現(xiàn)添加定時(shí)任務(wù)的方法,涉及java web定時(shí)任務(wù)控制類定義、調(diào)用及監(jiān)聽器定義、添加等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01Java CyclicBarrier源碼層分析與應(yīng)用
這篇文章主要介紹了Java CyclicBarrier的源碼層分析與應(yīng)用,CyclicBarrier也叫同步屏障,可以讓一組線程達(dá)到一個(gè)屏障時(shí)被阻塞,直到最后一個(gè)線程達(dá)到屏障,感興趣的的朋友可以參考下2023-12-12java使用動(dòng)態(tài)代理來實(shí)現(xiàn)AOP(日志記錄)的實(shí)例代碼
AOP(面向方面)的思想,就是把項(xiàng)目共同的那部分功能分離開來,比如日志記錄,避免在業(yè)務(wù)邏輯里面夾雜著跟業(yè)務(wù)邏輯無關(guān)的代碼2013-09-09Spring?Boot項(xiàng)目獲取resources目錄下文件并返回給前端的方案
我們在項(xiàng)目中經(jīng)常碰到需要讀取固定文件的場景,如模板文件,一般做法是將文件放在resources目錄下,程序通過多種方式可以順利讀取文件,這篇文章主要給大家介紹了關(guān)于Spring?Boot項(xiàng)目獲取resources目錄下文件并返回給前端的相關(guān)資料,需要的朋友可以參考下2024-07-07