解決SpringMVC 返回Java8 時(shí)間JSON數(shù)據(jù)的格式化問題處理
有時(shí)在Spring MVC中返回JSON格式的response的時(shí)候會使用@ResponseBody注解,不過在處理java8中時(shí)間的時(shí)候會很麻煩,一般我們使用的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"
}
}
但是我們不會返回這種給前端使用,針對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)是可以針對具體域類型設(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以針對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)換為對象時(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對象設(shè)置為JsonUtil中的objectMapper對象,此轉(zhuǎn)換器比spring內(nèi)置的json轉(zhuǎn)換器優(yōu)先級更高,所以與json有關(guān)的轉(zhuǎn)換,spring會優(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)對pojo中的某個(gè)域做特殊處理。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Kotlin與java8的SAM轉(zhuǎn)換對比(進(jìn)階)
這篇文章主要介紹了Kotlin與java8的SAM轉(zhuǎn)換對比,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
JavaEE實(shí)現(xiàn)前后臺交互的文件上傳與下載
這篇文章主要介紹了JavaEE實(shí)現(xiàn)前后臺交互的文件上傳與下載,分享相關(guān)技術(shù),實(shí)現(xiàn)文件上傳下載功能,需要的朋友可以參考下2015-11-11
Java 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-01
Java CyclicBarrier源碼層分析與應(yīng)用
這篇文章主要介紹了Java CyclicBarrier的源碼層分析與應(yīng)用,CyclicBarrier也叫同步屏障,可以讓一組線程達(dá)到一個(gè)屏障時(shí)被阻塞,直到最后一個(gè)線程達(dá)到屏障,感興趣的的朋友可以參考下2023-12-12
java使用動(dòng)態(tài)代理來實(shí)現(xiàn)AOP(日志記錄)的實(shí)例代碼
AOP(面向方面)的思想,就是把項(xiàng)目共同的那部分功能分離開來,比如日志記錄,避免在業(yè)務(wù)邏輯里面夾雜著跟業(yè)務(wù)邏輯無關(guān)的代碼2013-09-09
Spring?Boot項(xiàng)目獲取resources目錄下文件并返回給前端的方案
我們在項(xiàng)目中經(jīng)常碰到需要讀取固定文件的場景,如模板文件,一般做法是將文件放在resources目錄下,程序通過多種方式可以順利讀取文件,這篇文章主要給大家介紹了關(guān)于Spring?Boot項(xiàng)目獲取resources目錄下文件并返回給前端的相關(guān)資料,需要的朋友可以參考下2024-07-07

