在开发中,有时听到其它项目的同事说前端展示的时间差了8小时,是由于时区的问题,因为中国恰好是GMT+8,比格林尼治时间早了8小时。但奇怪的是,为什么我们项目就没有碰到过呢?于是,特别写了一个简单的例子,确认了一下我们的确实没有问题,并咨询了其它项目组同事是怎么出现的,特在此记录一下。
一.写一个简单的demo,还原各种场景
定义Controller
@RequestMapping("/list") public String showAll(ModelMap modelMap) { List<Article> articles = mapper.getArticlesByUserId(1); modelMap.addAttribute("articles", articles); return "main.ftl"; } @RequestMapping("/list2") public ModelAndView listall(HttpServletRequest request, HttpServletResponse response) { List<Article> articles = mapper.getArticlesByUserId(1); ModelAndView mav = new ModelAndView("list"); mav.addObject("articles", articles); return mav; } @ResponseBody @RequestMapping("/list3") public Map<String, Object> listall3(HttpServletRequest request, HttpServletResponse response) { List<Article> articles = mapper.getArticlesByUserId(1); Map<String, Object> map = new HashMap<String, Object>(); map.put("articles", articles); return map; }
1./list通过freemark模板展示,时间显示OK
<#list articles as article> <div>${article.id}. ${article.title}: ${article.content}: ${(article.updateTime)?string("yyyy-MM-dd HH:mm:ss")}</div> </#list>
访问请求,没有时间问题,如下所示:
2./list2通过jsp显示,时间也OK
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>article list</title> </head> <body> <c:forEach items="${articles}" var="item"> ${item.id }--${item.title }--${item.content}--${item.updateTime}<br /> </c:forEach> </body> </html>
访问请求,没有时间问题,如下所示:
3./list3直接返回map,json串展示
时间字段变成了长整型显示,但时间还是对的,在我们项目实际应用中,前端JS转换成字符串展示出来。
原来其它出问题的项目,他们是在后台的时间字段上通过@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")方式转换成字符串,然后直接在前端展示的。
于是,我把Article.java的updateTime字段上加上@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")注解,再次请求页面显示如下,updateTime比数据库中的真正时间晚了8小时:
在《SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(下)》一文中,我们知道,转换为JSON格式的对象提供前端显示,这个过程被Spring MVC的@RestController 注解识别并使用MappingJackson2HttpMessageConverter 进行消息转换,而我们的工程中都有jackson,且Jackson在对时间类型字段序列化(java.util.Date类型format为字符串)时是以GMT+0进行的,而不是"本地化"的时区设置。Jackson FAQ: Date Handling:All time objects that have associated TimeZone (java.util.Calendar etc) that Jackson constructs use the standard timezone (GMT), not the local time zone (whatever that might be). That is: Jackson defaults to using GMT for all processing unless specifically told otherwise.
查资料发现,这个问题可以通过设置主机默认时区来解决,如下所示:
但,通过查看源码,publicvoidconfigure(ObjectMapper objectMapper)方法里面设置的timezone恰好是没有赋值的。
二.解决办法
1.直接返回Date类型,让前端js或jsp来处理
2.Spring MVC的配置文件中的标签<mvc:annotation-driven>会默认实例化各种消息转换对象实例,解决上述问题的关键就是用自定的带时区的JSON消息转换器替换默认的。
<mvc:annotation-driven></mvc:annotation-driven>
修改为:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="com.fasterxml.jackson.databind.ObjectMapper"> <property name="timeZone"> <bean class="java.util.TimeZone" factory-method="getDefault" /> </property> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
实例代码见附件。
参考文章:https://blog.csdn.net/oShuSheng1/article/details/49614867
相关推荐
springsecurity前端素材
狂神SpringBoot项目中SpringSecurity课程用到的前端静态资源。
项目名: 酒店管理系统 功能点: 酒店管理,OTA直连 技术栈: 前端: react网页web框架,app 使用谷歌跨平台框架 flutter 后端: springcloud全家桶 项目名: 酒店管理系统 功能点: 酒店管理,OTA直连 技术栈: 前端...
基于Spring Mvc框架的Java Web项目的前端页面
普通javaweb项目调用springCloud接口(超级实用,很详细)但是要注意的事一定要对springboot和springcloud的有所了解,不然的话你也是看不懂的,大家一起努力共同学习
核心技术采用Eureka、Fegin、Ribbon、Zuul、Hystrix、Security、OAth、Mybatis、Ace-cache等主要框架和中间件,UI采用Bootstrap、jquery等前端组件 spring boot项目是使用spring boot + thymeleaf 开发个人博客项目
资源包括了spring-framework所有jar和junit、log4j、commons-logging等spring项目所需jar,完整全面,构建基础spring项目,下载这个足够了。
基于Spring Cloud微服务化电商平台,每个模块单独封装,如有某个模块不能满足业务,可以单独进行改造,无需关心其他模块功能, 各个模块之间通过Fegin调用,多业务系统并行开发,可以用来学习了解Spring Cloud各个...
前端:Vue + TypeScript + ElementUI,后端 Spring + Spark 毕设项目:商品大数据实时推荐系统。前端:Vue + TypeScript + ElementUI,后端 Spring + Spark 毕设项目:商品大数据实时推荐系统。前端:Vue + ...
一个完整结构 spring cloud 分布式项目 基于spring boot
第3篇是Spring MVC技术入门,包括Spring MVC的背景介绍、架构整体剖析、环境搭建、处理器与映射器的讲解、前端控制器的源码分析、多种视图解析器的介绍、请求映射与参数绑定的介绍、Validation校验与异常处理和拦截...
spring boot项目和vue一起放在tomcat部署,spring boot项目和vue一起放在tomcat部署
vue+spring boot网盘练习项目前端代码之登陆注册页面
论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts...
Spring Cloud项目实例,包括注册,负载配置,分布式配置,网关及调用
2022-本科毕业设计-基于Spring Cloud的ERP系统-前端项目.zip 1、该资源内项目代码经过严格调试,下载即用确保可以运行! 2、该资源适合计算机相关专业(如计科、人工智能、大数据、数学、电子信息等)正在做课程设计、...
spring mvc maven项目,导入IDEA后无报错,需要在IDEA中...该项目使用servlet3.0规范,无web.xml,无spring.xml等配置文件,所有的配置均通过Java Config、注解搞定,项目中还集成了log4j2技术,以及前端html文件等。
这是结合博客的源码,链接是:http://blog.csdn.net/u012660464/article/details/53508757 。名为:Spring MVC+Maven 实现同一项目的前端和后台交互,该源码示例了前端和后台如何进行参数的绑定传递。
此项目是使用Spring Boot 2.0后台技术 + SubLine 3处理 前台页面,页面模板使用BootStrap开发