1. 程式人生 > >SpringMVC4.1+FastJson 自定義日期轉換器

SpringMVC4.1+FastJson 自定義日期轉換器

對於有的時候要輸出日期格式為yyyy-MM-dd,而有的時候要輸出yyyy-MM-dd hh:mm:ss時怎麼辦?

第一種方案:純註解式, 對日期型別的欄位進行註解

@JSONField(format = "yyyy-MM-dd")
private Date updateDate;

@JSONField(format = "yyyy-MM-dd hh:mm:ss")
private Date createDate;

public Date getUpdateDate(){
    return updateDate;
}

publicvoidsetUpdateDate(Date updateDate)
{     this.updateDate = updateDate; } publicvoidsetCreateDate(Date createDate){     this.createDate = createDate; } public Date getCreateDate(){     return createDate; }

第二種方案:使用fastjson的<value>WriteDateUseDateFormat</value>配置(使得返回的日期型別預設為yyyy-MM-dd hh:mm:ss), 特殊型別使用欄位@JSONField來進行控制

<!-- 預設的註解對映的支援,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping -->
<mvc:annotation-drivencontent-negotiation-manager="contentNegotiationManager">    <mvc:message-convertersregister-defaults="true">       <!-- 將Jackson2HttpMessageConverter的預設格式化輸出為true -->       <!-- 配置Fastjson支援 -->       <beanclass="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"
>
         <propertyname="supportedMediaTypes">             <list>                <value>text/html;charset=UTF-8</value>                <value>application/json</value>             </list>          </property>          <propertyname="features">             <list>                <!-- 輸出key時是否使用雙引號 -->                <value>QuoteFieldNames</value>                <!-- 是否輸出值為null的欄位 -->                <!-- <value>WriteMapNullValue</value> -->                <!-- 數值欄位如果為null,輸出為0,而非null -->                <value>WriteNullNumberAsZero</value>                <!-- List欄位如果為null,輸出為[],而非null -->                <value>WriteNullListAsEmpty</value>                <!-- 字元型別欄位如果為null,輸出為"",而非null -->                <value>WriteNullStringAsEmpty</value>                <!-- Boolean欄位如果為null,輸出為false,而非null -->                <value>WriteNullBooleanAsFalse</value>                <!-- null String不輸出  -->                <value>WriteNullStringAsEmpty</value>                <!-- null String也要輸出  -->                <!-- <value>WriteMapNullValue</value> -->                                <!-- Date的日期轉換器 -->                <value>WriteDateUseDateFormat</value>             </list>          </property>       </bean>    </mvc:message-converters> </mvc:annotation-driven> <!-- REST中根據URL字尾自動判定Content-Type及相應的View --> <beanid="contentNegotiationManager"class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">    <propertyname="mediaTypes" >       <map>          <entrykey="json"value="application/json"/>       </map>    </property>    <!-- 這裡是否忽略掉accept header,預設就是false -->    <propertyname="ignoreAcceptHeader"value="true"/>    <propertyname="favorPathExtension"value="true"/> </bean>
@JSONField(format = "yyyy-MM-dd")
private Date updateDate;

public Date getUpdateDate(){
    return updateDate;
}

publicvoidsetUpdateDate(Date updateDate){
    this.updateDate = updateDate;
}

第三種方案:使用FastJson的訊息轉換器, 特殊型別使用欄位@JSONField來進行控制

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;
import java.io.OutputStream;

/**
 * 如果沒有注入預設的日期格式,也沒有配置<value>WriteDateUseDateFormat</value>, 也沒有屬性註解@JSONField(format="yyyy-MM-dd hh:mm:ss") 則會轉換輸出時間戳
 * 如果只配置<value>WriteDateUseDateFormat</value>,則會轉換輸出yyyy-MM-dd hh:mm:ss
 * 配置<value>WriteDateUseDateFormat</value>, 屬性註解@JSONField(format="yyyy-MM-dd hh:mm:ss") 則會轉換輸出為屬性註解的格式
 * 如果注入了預設的日期格式,屬性註解@JSONField(format="yyyy-MM-dd hh:mm:ss") 則會轉換輸出為屬性註解的格式
 * 如果注入了預設的日期格式,則會轉換輸出為預設的日期格式
 * 如果三者都配置則會轉換成屬性註解的格式
 * Created by PETER on 2016/2/5.
 */
public classCustomerFastJsonHttpMessageConverterextendsFastJsonHttpMessageConverter{

    public static SerializeConfig mapping = new SerializeConfig();

    private String defaultDateFormat;

    @Override
    protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        OutputStream out = outputMessage.getBody();
        String text = JSON.toJSONString(obj, mapping, super.getFeatures());
        byte[] bytes = text.getBytes(getCharset());
        out.write(bytes);
    }

    public void setDefaultDateFormat(String defaultDateFormat) {
        mapping.put(java.util.Date.class, new SimpleDateFormatSerializer(defaultDateFormat));
    }
}
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
      http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"><description>Spring MVC Configuration</description><!-- 載入配置屬性檔案 --><context:property-placeholderignore-unresolvable="true"location="classpath:/xmutca.properties" /><!-- 掃描dubbo註解需要在controller之前,否則會造成無法注入的問題 --><dubbo:annotationpackage="com.xmutca"></dubbo:annotation><!-- 使用Annotation自動註冊Bean,只掃描@Controller --><context:component-scanbase-package="com.xmutca"use-default-filters="false"><!-- base-package 如果多個,用“,”分隔 --><context:include-filtertype="annotation"expression="org.springframework.stereotype.Controller"/></context:component-scan><!-- 預設的註解對映的支援,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping --><mvc:annotation-drivencontent-negotiation-manager="contentNegotiationManager"><mvc:message-convertersregister-defaults="true"><!-- 將Jackson2HttpMessageConverter的預設格式化輸出為true --><!-- 配置Fastjson支援 --><beanclass="com.ydyx.core.web.converter.CustomerFastJsonHttpMessageConverter"><propertyname="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value><value>application/json</value></list></property><propertyname="features"><list><!-- 輸出key時是否使用雙引號 --><value>QuoteFieldNames</value><!-- 是否輸出值為null的欄位 --><!-- <value>WriteMapNullValue</value> --><!-- 數值欄位如果為null,輸出為0,而非null --><value>WriteNullNumberAsZero</value><!-- List欄位如果為null,輸出為[],而非null --><value>WriteNullListAsEmpty</value><!-- 字元型別欄位如果為null,輸出為"",而非null --><value>WriteNullStringAsEmpty</value><!-- Boolean欄位如果為null,輸出為false,而非null --><value>WriteNullBooleanAsFalse</value><!-- null String不輸出  --><value>WriteNullStringAsEmpty</value><!-- null String也要輸出  --><!-- <value>WriteMapNullValue</value> --></list></property><propertyname="defaultDateFormat"value="yyyy-MM-dd"></property></bean></mvc:message-converters></mvc:annotation-driven><!-- REST中根據URL字尾自動判定Content-Type及相應的View --><beanid="contentNegotiationManager"class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"><propertyname="mediaTypes" ><map><entrykey="json"value="application/json"/></map></property><!-- 這裡是否忽略掉accept header,預設就是false --><propertyname="ignoreAcceptHeader"value="true"/><propertyname="favorPathExtension"value="true"/></bean><!-- 檢視檔案解析配置 --><beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"><propertyname="prefix"value="${web.view.prefix}"/><propertyname="suffix"value="${web.view.suffix}"/></bean><!-- 對靜態資原始檔的訪問, 將無法mapping到Controller的path交給default servlet handler處理 --><mvc:default-servlet-handler/><!-- 定義無Controller的path<->view直接對映 --><mvc:view-controllerpath="/"view-name="redirect:${web.view.index}"/><!-- 基於註解式子的異常處理 --><beanid="exceptionHandlerExceptionResolver"class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean><!-- Shiro end --><!-- 上傳檔案攔截,設定最大上傳檔案大小   10M=10*1024*1024(B)=10485760 bytes --><beanid="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><propertyname="maxUploadSize"value="${web.maxUploadSize}" /></bean></beans>

第四種方案:使用SpringMVC的自定義屬性編輯器

@InitBinder
protectedvoidinitBinder(WebDataBinder binder){
    // String型別轉換,將所有傳遞進來的String進行前後空格處理, null字串處理
    binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
        @Override
        publicvoidsetAsText(String text){
            setValue(text == null ? null : text.trim());
        }

        @Override
        public String getAsText(){
            Object value = getValue();
            return value != null ? value.toString() : "";
        }
    });

    // Date 型別轉換
    binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
        @Override
        publicvoidsetAsText(String text){
            setValue(DateUtils.parseDate(text));
        }