SpringMVC4.1+FastJson 自定義日期轉換器
阿新 • • 發佈:2019-01-07
對於有的時候要輸出日期格式為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));
}