解决SpringMVC 返回Java8 时间JSON数据的格式化问题处理
有时在Spring MVC中返回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-26 21: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注解,如下 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; } 这种方式的优点是可以针对具体域类型设置不同显示方式,然而优点也是缺点,因为每个日期属性都要手动添加,实际中日期属性又是普遍必备,并且需要额外引入jsr310的jar包。 解决方法二: 继承ObjectMapper来实现返回json字符串。MappingJackson2HttpMessageConverter主要通过ObjectMapper来实现返回json字符串。这里我们编写一个JsonUtil类,获取ObjectMapper以针对java8中新的日期时间API,注册相应的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("转换json字符失败!"); } } public <T> T toObject(String json,Class<T> clazz) { try { return mapper.readValue(json,clazz); } catch (IOException e) { throw new RuntimeException("将json字符转换为对象时失败!"); } } } 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,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,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"> <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中的几种日期和时间类型就可以正常友好的显示了。优点是全局统一管理日期和时间等类型,缺点对pojo中的某个域做特殊处理。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |