一、关于SpringMVC日期的格式化大概可分为四点
1.@ResponseBody方式返回json的日期格式化
2.ajax方式返回json的日期格式化
3.数据保存时String转Date
4.页面展示时,Date转固定格式的String
二、配置实现日期格式化
无配置的json数据,日期显示为timestamp
{"id":8,"loginName":"chensan","loginPwd":"123456","userName":"陈三","mnemonic":null,"sex":2,"birthday":631123200000,"status":1,"createBy":1,"createDatetime":1527955762000,"updateBy":1,"updateDatetime":1528040703000,"delFlag":null,"remark":"xsdssds说到底发生的bbbbb","roleIds":null}
1.@ResponseBody方式返回json的日期格式化
在com.fasterxml.jackson.databind.ObjectMapper设置相应属性
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS默认为true,日期显示为时间戳;
修改为false
{"id":8,"loginName":"chensan","loginPwd":"123456","userName":"陈三","mnemonic":null,"sex":2,"birthday":"1989-12-31T16:00:00.000+0000","status":1,"createBy":1,"createDatetime":"2018-06-02T16:09:22.000+0000","updateBy":1,"updateDatetime":"2018-06-03T15:45:03.000+0000","delFlag":null,"remark":"xsdssds说到底发生的bbbbb","roleIds":null}
时区默认0时区,设置东八区timezone="GMT+8"
{"id":8,"loginName":"chensan","loginPwd":"123456","userName":"陈三","mnemonic":null,"sex":2,"birthday":"1990-01-01T00:00:00.000+0800","status":1,"createBy":1,"createDatetime":"2018-06-03T00:09:22.000+0800","updateBy":1,"updateDatetime":"2018-06-03T23:45:03.000+0800","delFlag":null,"remark":"xsdssds说到底发生的bbbbb","roleIds":null}
日期格式化DateFormat设置为"yyyy-MM-dd HH:mm:ss"格式
{"id":8,"loginName":"chensan","loginPwd":"123456","userName":"陈三","mnemonic":null,"sex":2,"birthday":"1990-01-01 00:00:00","status":1,"createBy":1,"createDatetime":"2018-06-03 00:09:22","updateBy":1,"updateDatetime":"2018-06-03 23:45:03","delFlag":null,"remark":"xsdssds说到底发生的bbbbb","roleIds":null}
无时分秒的日期,时分秒以0补齐,如:birthday,需要在字段上设置@JsonFormat(pattern=”yyyy-MM-dd”);用以覆盖ObjectMapper中的配置 ;
也可以不配置ObjectMapper中相应的配置,只须在日期字段设置@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")配置日期格式和时区,根据实际情况设置日期格式和时区;
{"id":8,"loginName":"chensan","loginPwd":"123456","userName":"陈三","mnemonic":null,"sex":2,"birthday":"1990-01-01","status":1,"createBy":1,"createDatetime":"2018-06-03 00:09:22","updateBy":1,"updateDatetime":1528040703000,"delFlag":null,"remark":"xsdssds说到底发生的bbbbb","roleIds":null}这个返回的json去掉了jackson的ObjectMapper配置,配置了 @JsonFormat的字段也不会以时间戳显示;
当然,建议统一设置jackson配置;
public class CustomObjectMapper extends ObjectMapper { private static final long serialVersionUID = 1L; public CustomObjectMapper() { //禁止使用时间戳 this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); //设置为中国上海时区 this.setTimeZone(TimeZone.getTimeZone("GMT+8")); //设置日期格式 this.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); //反序列化时,属性不存在的兼容处理 //this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); //如果是空对象的时候,不抛异常 //this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); //反序列化的时候如果多了其他属性,不抛出异常 //this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //单引号处理 //this.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); } }
springmvc配置文件
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper" ref="jacksonObjectMapper" /> </bean> </mvc:message-converters> </mvc:annotation-driven> <bean id="jacksonObjectMapper" class="com.chensan.config.CustomObjectMapper" />
参考:https://www.cnblogs.com/lcngu/p/5785805.html
https://www.cnblogs.com/coder6/p/6738781.html
Spring3.x和Spring4.x的配置有区别,参考:https://blog.csdn.net/m0_38016299/article/details/78338048
2.ajax方式返回json的日期格式化
非@ResponseBody的日期格式化
BaseController
public class BaseController { protected static final Logger loger = LoggerFactory.getLogger(BaseController.class); protected static SerializeConfig mapping = new SerializeConfig(); protected static String dateFormat; static { dateFormat = "yyyy-MM-dd HH:mm:ss"; mapping.put(Date.class, new SimpleDateFormatSerializer(dateFormat)); } /** * 向客户端输出html字符串 * @param response HttpServletResponse响应 * @param content 要输出到客户端的字符串 */ public void writeResponse(HttpServletResponse response, String content) { response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=UTF-8"); PrintWriter writer; try { writer = response.getWriter(); writer.write(content); writer.flush(); } catch (IOException e) { loger.error("向客户端写入数据失败", e); } } /** * 根据MIME类型输出响应内容。 * @param response HttpServletResponse响应 * @param content 要输出到客户端的字符串 * @param contentType 输出ContentType */ public void writeResponseByMIME(HttpServletResponse response, String content, String contentType) { response.setCharacterEncoding("utf-8"); response.setContentType(contentType + "; charset=UTF-8"); PrintWriter writer; try { writer = response.getWriter(); writer.write(content); writer.flush(); } catch (IOException e) { loger.error("向客户端写入数据失败", e); } } }
Controller继承BaseController
/** * 测试ajax方式(非@ResponseBody注解方式)获取json数据 * @param id * @param response * 可以看到非@ResponseBody注解(ajax)方式获取的json格式为时间戳格式, 故而在BaseController对日期格式化 * 这里用的json包围fastjson,所以设置SerializeConfig,字段上注解用@JSONField(format="yyyy-MM-dd HH:mm:ss"),具体格式根据需要自定义 * */ @RequestMapping("/getJsonData2/{id}") public void ajaxGetJsonData(@PathVariable(value = "id") Integer id, HttpServletResponse response) { User entity = userService.queryById(id); JSONPObject jsonp = new JSONPObject(); jsonp.addParameter(entity); String jsonResult = JSON.toJSONString(jsonp, BaseController.mapping, SerializerFeature.WriteMapNullValue); this.writeResponseByMIME(response, jsonResult, MimeTypeUtils.APPLICATION_JSON_VALUE); } /** * fastjson过滤字段 * @param id * @param response */ @RequestMapping("/getJsonData3/{id}") public void ajaxGetJsonData2(@PathVariable(value = "id") Integer id, HttpServletResponse response) { User entity = userService.queryById(id); JSONPObject jsonp = new JSONPObject(); jsonp.addParameter(entity); SimplePropertyPreFilter filter = new SimplePropertyPreFilter(User.class, "id", "userName", "loginName", "birthday", "sex", "status", "createDatetime", "updateDatetime"); String jsonResult = JSON.toJSONString(jsonp, BaseController.mapping, filter, SerializerFeature.WriteMapNullValue); this.writeResponseByMIME(response, jsonResult, MimeTypeUtils.APPLICATION_JSON_VALUE); }
null({"birthday":"1990-01-01 00:00:00","createBy":1,"createDatetime":"2018-06-03 00:09:22","delFlag":null,"id":8,"loginName":"chensan","loginPwd":"123456","mnemonic":null,"remark":"xsdssds说到底发生的bbbbb","roleIds":null,"sex":2,"status":1,"updateBy":1,"updateDatetime":"2018-06-03 23:45:03","userName":"陈三"})
BaseController设置日期格式为"yyyy-MM-dd HH:mm:ss",birthday只有年月日需要在字段自定义格式@JSONField (format="yyyy-MM-dd")
3.数据保存时String转Date
数据保存时,页面的String不转为Date,则字段类型无法匹配,数据不能保存。在Model设置注解@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss"),将字符串格式化,@DateTimeFormat能将String自动转为Date;至于ConversionServiceFactoryBean,实在没必要啊,我最初还以为是可以将页面展示的日期格式化为"yyyy-MM-dd HH:mm:ss"格式才试了试。
ConversionServiceFactoryBean配置,参考:https://www.cnblogs.com/ssslinppp/p/4600043.html
4.页面展示时,Date转固定格式的String
页面不格式化的日期,如:Sun Jun 03 00:09:22 CST 2018
1.模板用format标签就行了,所有模板引擎都有提供
2.用spring的标签<%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>,
<s:eval expression="formModel.createDatetime"/>需要搭配@DateTimeFormat标签使用
参考:https://www.cnblogs.com/liukemng/p/3748137.html
3.还有就是在js调用格式化
/ 自定义日期格式化 Date.prototype.Format = function (fmt) { var o = { "M+": this.getMonth() + 1, // 月份 "d+": this.getDate(), // 日 "h+": this.getHours(), // 小时 "m+": this.getMinutes(), // 分 "s+": this.getSeconds(), // 秒 "q+": Math.floor((this.getMonth() + 3) / 3), // 季度 "S": this.getMilliseconds() // 毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); return fmt; }
或者用日期选择器插件,初始化日期
4.见过最邪门的是公司的SpringCloud项目,去掉了所有配置文件的日期格式化,去掉了硬编码的java类配置与日期格式化相关的类,字段也没调用js和用format标签,但是thyemeleaft模板就是将日期格式化了。(问了老大本人,他指出所有配置的地方,奈何我已全测试过不顶用才去问的;项目很久他忘了是怎么配置的。实在搞不定,只能等把整个项目完全消化掉再去看了)