spring mvc 使用及json 日期轉換解決方案
第一步:建立CustomObjectMapper類
- /**
- * 解決SpringMVC使用@ResponseBody返回json時,日期格式預設顯示為時間戳的問題。需配合<mvc:message-converters>使用
- *
- * @author hellostory
- * @date 2013-10-31 下午04:17:52
- */
- @Component("customObjectMapper")
- public class CustomObjectMapper extends ObjectMapper {
-
public CustomObjectMapper() {
- CustomSerializerFactory factory = new CustomSerializerFactory();
- factory.addGenericMapping(Date.class, new JsonSerializer<Date>() {
- @Override
- public void serialize(Date value, JsonGenerator jsonGenerator,
-
SerializerProvider provider) throws IOException, JsonProcessingException {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- jsonGenerator.writeString(sdf.format(value));
- }
- });
- this.setSerializerFactory(factory);
- }
- }
第二步:配置如下:
-
<mvc:annotation-driven
- <mvc:message-converters>
- <beanclass="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
- <propertyname="objectMapper"ref="customObjectMapper"></property>
- </bean>
- </mvc:message-converters>
- </mvc:annotation-driven>
效果如下:
格式化前:
格式化後:
又到搭新開發環境的時候,總是不免去網上搜下目前最新的框架。spring是web開發必用的框架,於是乎下載了目前最新的spring4.0.3,同時越來越不想用struts2,想試試spring mvc,也將spring-webmvc4.0.3下了下來,投入兩天時間學習後,發現還是挺優雅的,特別是從3.0後,spring mvc使用註解方式配製,以及對rest風格的支援,真是完美致極。
下面將這兩天研究到的問題做個總結,供參考。
1.request物件的獲取
方式1:在controller方法上加入request引數,spring會自動注入,如:public String list(HttpServletRequest request,HttpServletResponse response)
方式2:在controller類中加入@Resource private HttpServletRequest request 屬性,spring會自動注入,這樣不知道會不會出現執行緒問題,因為一個controller例項會為多個請求服務,暫未測試。
方式3:在controller方法中直接寫程式碼獲取 HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
方式4:在controller中加入以下方法,此方法會在執行此controller的處理方法之前執行
- @ModelAttribute
- privatevoid initServlet(HttpServletRequest request,HttpServletResponse response) {
- //String p=request.getParameter("p");
- //this.req=request;//例項變數,有執行緒安全問題,可以使用ThreadLocal模式儲存
- }
2.response物件的獲取
可以參照以上request的獲取方式1和方式4,方式2和方式3對response物件無效!3.表單提交之資料填充
直接在方法上加入實體物件引數,spring會自動填充物件中的屬性,物件屬性名要與<input>的name一致才會填充,如:public boolean doAdd(Demo demo)
4.表單提交之資料轉換-Date型別在實體類的屬性或get方法上加入 @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss"),那麼表單中的日期字串就會正確的轉換為Date型別了。還有@NumberFormat註解,暫時沒用,就不介紹了,一看就知道是對數字轉換用的。
5.json資料返回在方法上加入@ResponseBody,同時方法返回值為實體物件,spring會自動將物件轉換為json格式,並返回到客戶端。如下所示:
- @RequestMapping("/json1")
- @ResponseBody
- public Demo json1() {
- Demo demo=new Demo();
- demo.setBirthday(new Date());
- demo.setCreateTime(new Date());
- demo.setHeight(170);
- demo.setName("tomcat");
- demo.setRemark("json測試");
- demo.setStatus((short)1);
- return demo;
- }
這種方式是spring提供的,我們還可以自定義輸出json,以上第二條不是說了獲取response物件嗎,拿到response物件後,任由開發人員宰割,想怎麼返回就怎麼返回。
方法不要有返回值,如下:
- @RequestMapping("/json2")
- publicvoid json2() {
- Demo demo=new Demo();
- demo.setBirthday(new Date());
- demo.setCreateTime(new Date());
- demo.setHeight(170);
- demo.setName("tomcat");
- demo.setRemark("json測試");
- demo.setStatus((short)1);
- String json=JsonUtil.toJson(obj);//;json處理工具類
- HttpServletResponse response = //獲取response物件
- response.getWriter().print(json);
- }
先寫一個日期轉換器,如下:
- publicclass JsonDateSerializer extends JsonSerializer<Date> {
- private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- @Override
- publicvoid serialize(Date date, JsonGenerator gen, SerializerProvider provider)
- throws IOException, JsonProcessingException {
- String value = dateFormat.format(date);
- gen.writeString(value);
- }
- }
- @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
- @JsonSerialize(using=JsonDateSerializer.class)
- public Date getCreateTime() {
- returnthis.createTime;
- }
你真的滿意了嗎,這麼不優雅的解決方案,假設birthday屬性是這樣的,只有年月日,無時分秒
- @DateTimeFormat(pattern="yyyy-MM-dd")
- public Date getBirthday() {
- returnthis.birthday;
- }
- @DateTimeFormat(pattern="yyyy-MM-dd")
- @JsonSerialize(using=JsonDate2Serializer.class)
- public Date getBirthday() {
- returnthis.birthday;
- }
經過分析原始碼,找到一個不錯的方案,此方案將不再使用@JsonSerialize,而只利用@DateTimeFormat配置日期格式,jackson就可以正確轉換,但@DateTimeFormat只能配置在get方法上,這也沒什麼關係。
先引入以下類,此類對jackson的ObjectMapper類做了註解掃描攔截,使它也能對加了@DateTimeFormat的get方法應用日期格式化規則
- package com.xxx.