<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    cuiyi's blog(崔毅 crazycy)

    記錄點滴 鑒往事之得失 以資于發展
    數據加載中……

    SpringMVC+MyBatis - 12 spring mvc4返回的json日期為Long的解決方案

    Spring MVC 4.X ResponseBody 日期類型Json 處理

    摘自http://tramp-zzy.iteye.com/blog/2090330  2014-07-10
    方法一:全局處理
    <mvc:annotation-driven>  
        <!-- 處理responseBody 里面日期類型 -->  
            <mvc:message-converters>  
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">  
                    <property name="objectMapper">  
                        <bean class="com.fasterxml.jackson.databind.ObjectMapper">  
                            <property name="dateFormat">  
                                <bean class="java.text.SimpleDateFormat">  
                                    <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />  
                                </bean>  
                            </property>  
                        </bean>  
                    </property>  
                </bean>  
            </mvc:message-converters>  
        </mvc:annotation-driven>  
    方法二:局部注解處理 
    import java.io.IOException;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  
      
    import com.fasterxml.jackson.core.JsonGenerator;  
    import com.fasterxml.jackson.core.JsonProcessingException;  
    import com.fasterxml.jackson.databind.JsonSerializer;  
    import com.fasterxml.jackson.databind.SerializerProvider;  
      
    /**  
     * ClassName:DateJsonSerializer <br/>  
     * Function: 日期類型格式化,格式化為:yyyy-MM-dd HH:mm:ss 格式. 用法如下:<br/>  
     * Reason:   @JsonSerialize(using=DateJsonSerializer.class) 
     *           @Column(name="BIRTHDAY") 
     *           public Date getBirthday() { 
     *              return birthday; 
     *           } 
     *          . <br/>  
     * Date:     2014年7月10日 下午1:26:08 <br/>  
     * 
    @author   zhangzhaoyu  
     * 
    @version   1.0 
     * 
    @since    JDK 1.7  
     * 
    @see        
     
    */  
    public class DateJsonSerializer extends JsonSerializer<Date> {  
      
        @Override  
        public void serialize(Date value, JsonGenerator jgen,  
                SerializerProvider provider) throws IOException,  
                JsonProcessingException {  
             SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
             String formattedDate = formatter.format(value);  
             jgen.writeString(formattedDate);  
        }  
      
    }  
    方法三:jackson 注解處理
    @JsonIgnoreProperties  
             此注解是類注解,作用是json序列化時將java bean中的一些屬性忽略掉,序列化和反序列化都受影響。  
      
    @JsonIgnore  
             此注解用于屬性或者方法上(最好是屬性上),作用和上面的@JsonIgnoreProperties一樣。  
      
    @JsonFormat  
            此注解用于屬性或者方法上(最好是屬性上),可以方便的把Date類型直接轉化為我們想要的模式,比如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")  
      
    @JsonSerialize  
      
     // 反序列化一個固定格式的Date    
        @JsonDeserialize(using = CustomDateDeserialize.class)    
        public void setBirthday(Date birthday) {    
            this.birthday = birthday;    
        }   
      
     // 序列化指定格式的double格式    
        @JsonSerialize(using = CustomDoubleSerialize.class)    
        public double getSalary() {    
            return salary;    
        }    
      
    public class CustomDateDeserialize extends JsonDeserializer<Date> {    
        
        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");    
        
        @Override    
        public Date deserialize(JsonParser jp, DeserializationContext ctxt)    
                throws IOException, JsonProcessingException {    
        
            Date date = null;    
            try {    
                date = sdf.parse(jp.getText());    
            } catch (ParseException e) {    
                e.printStackTrace();    
            }    
            return date;    
        }    
    }   


    spring mvc4使用及json 日期轉換解決方案

    摘自:http://blog.csdn.net/zhanngle/article/details/24123659  2014-04-19
    又到搭新開發環境的時候,總是不免去網上搜下目前最新的框架。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  
    private void 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配置文件要加上:<mvc:annotation-driven/>,同時還要引入jackson-core.jar,jackson-databind.jar,jackson-annotations.jar(2.x的包)才會自動轉換json
    這種方式是spring提供的。我們還可以自定義輸出json,以上第二條不是說了獲取response對象嗎,拿到response對象后,任由開發人員宰割,想怎么返回就怎么返回。
    方法不要有返回值,如下:
    @RequestMapping("/json2")  
    public void 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);  

    }  
    OK,一切很完美。接著惡心的問題迎面而來,date類型轉換為json字符串時,返回的是long time值,如果你想返回“yyyy-MM-dd HH:mm:ss”格式的字符串,又要自定義了。我很奇怪,不是有@DateTimeFormat注解嗎,為什么不利用它。難道@DateTimeFormat只在表單提交時,將字符串轉換為date類型,而date類型轉換為json字符串時,就不用了。帶著疑惑查源碼,原來spring使用jackson轉換json字符,而@DateTimeFormat是spring-context包中的類,jackson如何轉換,spring不方便作過多干涉,于是只能遵守jackson的轉換規則,自定義日期轉換器。
    先寫一個日期轉換器,如下:
    public class JsonDateSerializer extends JsonSerializer<Date> {  
       private SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
       @Override  
       public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)  throws IOException, JsonProcessingException {  
           String value = dateFormat.format(date);  
           gen.writeString(value);  
       }  
    }  
    在實體類的get方法上配置使用轉換器,如下:
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")  
    @JsonSerialize(using=JsonDateSerializer.class)  
    public Date getCreateTime() {  
        return this.createTime;  
    }  
    OK,到此搞定。
    你真的滿意了嗎,這么不優雅的解決方案,假設birthday屬性是這樣的,只有年月日,無時分秒
    @DateTimeFormat(pattern="yyyy-MM-dd")  
    public Date getBirthday() {  
        return this.birthday;  
    }  
    這意味著,又要為它定制一個JsonDate2Serializer的轉換器,然后配置上,像這樣

    @DateTimeFormat(pattern="yyyy-MM-dd")  
    @JsonSerialize(using=JsonDate2Serializer.class)  
    public Date getBirthday() {  
        return this.birthday;  
    }  
    假設還有其它格式的Date字段,還得要為它定制另一個轉換器。my god,請饒恕我的罪過,不要讓我那么難受
    經過分析源碼,找到一個不錯的方案,此方案將不再使用@JsonSerialize,而只利用@DateTimeFormat配置日期格式,jackson就可以正確轉換,但@DateTimeFormat只能配置在get方法上,這也沒什么關系。
    先引入以下類,此類對jackson的ObjectMapper類做了注解掃描攔截,使它也能對加了@DateTimeFormat的get方法應用日期格式化規則
    package com.xxx.utils;  
      
    import java.io.IOException;  
    import java.lang.reflect.AnnotatedElement;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  
    import org.springframework.format.annotation.DateTimeFormat;  
    import org.springframework.stereotype.Component;  
    import com.fasterxml.jackson.core.JsonGenerator;  
    import com.fasterxml.jackson.core.JsonProcessingException;  
    import com.fasterxml.jackson.databind.JsonSerializer;  
    import com.fasterxml.jackson.databind.ObjectMapper;  
    import com.fasterxml.jackson.databind.SerializerProvider;  
    import com.fasterxml.jackson.databind.introspect.Annotated;  
    import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;  
    import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;  
      
    /** 
     * json處理工具類 
     * 
    @author zhangle 
     
    */  
    @Component  
    public class JsonUtil {  
            private static final String DEFAULT_DATE_FORMAT="yyyy-MM-dd HH:mm:ss";  
            private static final ObjectMapper mapper;  
              
            public ObjectMapper getMapper() {  
                    return mapper;  
            }  
      
            static {  
                    SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);  
                      
                    mapper = new ObjectMapper();  
                    mapper.setDateFormat(dateFormat);  
                    mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {  
                            @Override  
                            public Object findSerializer(Annotated a) {  
                                    if(a instanceof AnnotatedMethod) {  
                                            AnnotatedElement m=a.getAnnotated();  
                                            DateTimeFormat an=m.getAnnotation(DateTimeFormat.class);  
                                            if(an!=null) {  
                                                    if(!DEFAULT_DATE_FORMAT.equals(an.pattern())) {  
                                                            return new JsonDateSerializer(an.pattern());  
                                                    }  
                                            }  
                                    }  
                                    return super.findSerializer(a);  
                            }  
                    });  
            }  
              
            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字符轉換為對象時失敗!");  
                    }  
            }  
              
            public static class JsonDateSerializer extends JsonSerializer<Date>{  
                private SimpleDateFormat dateFormat;  
                public JsonDateSerializer(String format) {  
                     dateFormat = new SimpleDateFormat(format);  
                    }  
                  
                @Override  
                public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)  
                        throws IOException, JsonProcessingException {  
                    String value = dateFormat.format(date);  
                    gen.writeString(value);  
                }  
            }  
    }  
    再將<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>text/json;charset=UTF-8</value>  
                    </list>  
                </property>    
            </bean>  
        </mvc:message-converters>  
    </mvc:annotation-driven>  
    接下來就可以這樣配置實體類,jackson也能正確轉換Date類型
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")  
    public Date getCreateTime() {  
        return this.createTime;  
    }  
    @DateTimeFormat(pattern="yyyy-MM-dd")  
    public Date getBirthday() {  
        return this.birthday;  
    }  

    完畢,一切都完美了。


    以下為2014/4/21 補充

    寫了那么多,發現白忙活了一場,原來jackson也有一個@JsonFormat注解,將它配置到Date類型的get方法上后,jackson就會按照配置的格式轉換日期類型,而不自定義轉換器類,欲哭無淚啊。辛苦了那么多,其實別人早已提供,只是沒有發現而已。

    不說了,直接上方案吧。

    1.spring配置照樣是這樣:

    1. <mvc:annotation-driven>  
    2.JsonUtil可以不用了,但如果要自己從response對象輸出json,那么還是可以用,但改成了這樣
    package com.xxx.utils;  
      
    import java.io.IOException;  
    import java.text.SimpleDateFormat;  
    import org.springframework.stereotype.Component;  
    import com.fasterxml.jackson.databind.ObjectMapper;  
      
    /** 
     * json處理工具類 
     * 
    @author zhangle 
     
    */  
    @Component  
    public class JsonUtil {  
      
        private static final String DEFAULT_DATE_FORMAT="yyyy-MM-dd HH:mm:ss";  
        private static final ObjectMapper mapper;  
      
        static {  
            SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);  
            mapper = new ObjectMapper();  
            mapper.setDateFormat(dateFormat);  
        }  
          
        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字符轉換為對象時失敗!");  
            }  
        }  
    }

    3.實體類的get方法就需要多一個@JsonFormat的注解配置
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")  
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")  
    public Date getCreateTime() {  
    return this.createTime;  
    }  
    @DateTimeFormat(pattern="yyyy-MM-dd")  
    @JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")  
    public Date getBirthday() {  
        return this.birthday;  
    }  

    posted on 2014-07-15 14:30 crazycy 閱讀(37650) 評論(3)  編輯  收藏 所屬分類: JavaEE技術

    評論

    # re: SpringMVC+MyBatis - 12 spring mvc4返回的json日期為Long的解決方案  回復  更多評論   

    rklrmoproporp
    2015-10-30 17:11 | ldpe

    # re: SpringMVC+MyBatis - 12 spring mvc4返回的json日期為Long的解決方案[未登錄]  回復  更多評論   

    請問實體類有個字段叫name,序列json時,想把name替換成text,應該怎么做呢,在需要進行轉換時自定義,不用注解
    2016-05-24 15:48 | coder

    # re: SpringMVC+MyBatis - 12 spring mvc4返回的json日期為Long的解決方案  回復  更多評論   

    垃圾,根本沒用
    2016-08-07 23:47 | 省份
    主站蜘蛛池模板: 最近的中文字幕大全免费8| 大地资源中文在线观看免费版| 成人免费大片免费观看网站| 亚洲午夜无码久久久久| 成人免费无码H在线观看不卡| 四虎影视永久免费视频观看| 亚洲精品女同中文字幕| 国产一精品一aⅴ一免费| 特级做a爰片毛片免费看| 国产亚洲精品无码拍拍拍色欲| 一级一看免费完整版毛片| 区久久AAA片69亚洲| 嫩草在线视频www免费观看| 亚洲AV日韩AV永久无码绿巨人| 精品无码国产污污污免费网站| 亚洲午夜电影在线观看高清| 成人au免费视频影院| 全部在线播放免费毛片| 亚洲人成伊人成综合网久久久| 久久99国产乱子伦精品免费| 亚洲国产区男人本色在线观看| 国产一级大片免费看| 在线涩涩免费观看国产精品| 91亚洲视频在线观看| 国产免费小视频在线观看| 美女网站在线观看视频免费的| 亚洲第一成年男人的天堂| 青青青免费国产在线视频小草| 亚洲国产av玩弄放荡人妇| 亚洲中文字幕第一页在线| 99re在线这里只有精品免费| 亚洲成_人网站图片| 久久久久亚洲AV成人网| 麻豆高清免费国产一区| 亚洲乱妇熟女爽到高潮的片| 国产午夜亚洲不卡| 18禁免费无码无遮挡不卡网站| 国产亚洲成在线播放va| 亚洲视频在线免费看| 亚洲一区二区三区高清不卡 | 亚洲av午夜精品一区二区三区|