解决SpringMVC 返回Java8 时间JSON数据的格式化问题处理
有时在SpringMVC中返回JSON格式的response的时候会使用@ResponseBody注解,不过在处理java8中时间的时候会很麻烦,一般我们使用的HTTPMessageConverter是MappingJackson2HttpMessageConverter,它默认返回的时间格式是这种:
"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-2621:04:34这样的数据。通过项目研究并查阅相关资料,这里介绍下个人研究中实现的两种方式。
解决方法一:
若是maven项目,在pom中引入下面的jar包:
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.8.5</version> </dependency>
然后在你想要JSON化的POJO字段的get函数上加上一个@JsonSerializer注解,如下
importcom.fasterxml.jackson.annotation.JsonFormat;
@JsonFormat(shape=JsonFormat.Shape.STRING,pattern="yyyy-MM-dd")
publicLocalDateTimegetBirthday(){
returnthis.loginTime;
}
@JsonFormat(shape=JsonFormat.Shape.STRING,pattern="yyyy-MM-ddHH:mm:ss")
publicLocalDateTimegetLastLoginTime(){
returnthis.loginTime;
}
这种方式的优点是可以针对具体域类型设置不同显示方式,然而优点也是缺点,因为每个日期属性都要手动添加,实际中日期属性又是普遍必备,并且需要额外引入jsr310的jar包。
解决方法二:
继承ObjectMapper来实现返回json字符串。MappingJackson2HttpMessageConverter主要通过ObjectMapper来实现返回json字符串。这里我们编写一个JsonUtil类,获取ObjectMapper以针对java8中新的日期时间API,注册相应的JsonSerializer<T>。
/**
*json处理工具类
*
*
*/
@Component
publicclassJsonUtil{
privatestaticfinalObjectMappermapper;
publicObjectMappergetMapper(){
returnmapper;
}
static{
mapper=newObjectMapper();
SimpleModulemodule=newSimpleModule();
module.addSerializer(LocalDate.class,newLocalDateSerializer());
module.addSerializer(LocalTime.class,newLocalTimeSerializer());
module.addSerializer(LocalDateTime.class,newLocalDateTimeSerializer());
mapper.registerModule(module);
}
publicstaticStringtoJson(Objectobj){
try{
returnmapper.writeValueAsString(obj);
}catch(Exceptione){
thrownewRuntimeException("转换json字符失败!");
}
}
public<T>TtoObject(Stringjson,Class<T>clazz){
try{
returnmapper.readValue(json,clazz);
}catch(IOExceptione){
thrownewRuntimeException("将json字符转换为对象时失败!");
}
}
}
classLocalDateSerializerextendsJsonSerializer<LocalDate>{
privatestaticfinalDateTimeFormatterdateFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
publicvoidserialize(LocalDatevalue,JsonGeneratorjgen,SerializerProviderprovider)
throwsIOException,JsonProcessingException{
jgen.writeString(dateFormatter.format(value));
}
}
classLocalDateTimeSerializerextendsJsonSerializer<LocalDateTime>{
privatestaticfinalDateTimeFormatterdateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss");
@Override
publicvoidserialize(LocalDateTimevalue,JsonGeneratorjgen,SerializerProviderprovider)
throwsIOException,JsonProcessingException{
jgen.writeString(dateTimeFormatter.format(value));
}
}
classLocalTimeSerializerextendsJsonSerializer<LocalTime>{
privatestaticfinalDateTimeFormattertimeFormatter=DateTimeFormatter.ofPattern("HH:mm:ss");
@Override
publicvoidserialize(LocalTimevalue,JsonGeneratorjgen,SerializerProviderprovider)
throwsIOException,JsonProcessingException{
jgen.writeString(timeFormatter.format(value));
}
}
然后在springmvc的配置文件中,再将<mvc:annotation-driven/>改为以下配置,配置一个新的json转换器,将它的ObjectMapper对象设置为JsonUtil中的objectMapper对象,此转换器比spring内置的json转换器优先级更高,所以与json有关的转换,spring会优先使用它。
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<propertyname="objectMapper"value="#{jsonUtil.mapper}"/>
<propertyname="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
然后java8中的几种日期和时间类型就可以正常友好的显示了。优点是全局统一管理日期和时间等类型,缺点对pojo中的某个域做特殊处理。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。