轉載自:http://cfanz.cn/index.php?c=article&a=read&id=303559
一、問題
springMVC有一個比較奇葩的問題,就是如果接受參數是日期(java.util.Date)類型或者參數是包含了(java.util.Date)得POJO將會導致無法進入Controller的方法。沒想明白爲什麼spring作爲那麼成熟的框架沒有兼容這個問題。好了,不廢話了,下面講一下解決辦法(不一定是最佳方案,僅供參考)
二、解決辦法
1、網上解決辦法
其實spring提供了一種解決辦法(也是網上查到比較普遍的做法),就是在每一個Controller類裏面增加如下方法:
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(“”), true));
}
這種方法的缺陷:一個比較大的項目的話,可能需要有帶時間的日期,也有可能是不帶日期的日期,這種辦法只能兼用一種日期格式數據
2、我的解決辦法
基於上述方法,我查看了spring 這個CustomDateEditor類的源碼,其實這個類是提供了日期轉換功能。所以我的做法是
第一步:
寫一個自己的CustomDateEditor類,讓這個類擁有更加強大的日期轉換支持,具體代碼如下:
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import com.tl.core.exception.FrameworkException;
/**
*重寫spring日期轉換器,自定義日期轉換器
* @author zeliangmo
* mzl 2016-10-7
*/
public class MyCustomDateEditor extends PropertyEditorSupport {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* Parse the Date from the given text, using the specified DateFormat.
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (!StringUtils.hasText(text)) {
// Treat empty String as null value.
setValue(null);
}
else {
try {
setValue(this.dateAdapter(text));
}
catch (FrameworkException ex) {
ex.printStackTrace();
logger.error(“出錯日誌:”+ex.getMessage());
}
}
}
/**
* Format the Date as String, using the specified DateFormat.
*/
@Override
public String getAsText() {
Date value = (Date) getValue();
SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
return (value != null ? dateFormat.format(value) : “”);
}
/**
* 字符串轉日期適配方法
* @param dateStr 日期字符串
* @throws FrameworkException
*/
public static Date dateAdapter(String dateStr) throws FrameworkException {
Date date=null;
String temp=dateStr;//緩存原始數據
if(!(null==dateStr||“”.equals(dateStr))){
//判斷是不是日期字符串,如Wed May 28 08:00:00 CST 2014
if(dateStr.contains(“CST”)){
date=new Date(dateStr);
}else{
dateStr=dateStr.replace(“年”, “-“).replace(“月”, “-“).replace(“日”, “”).replaceAll(“/”, “-“).replaceAll(“\\.”, “-“).trim();
String fm=“”;
//確定日期格式
if(Pattern.compile(“^[0-9]{4}-[0-9]{2}-[0-9]{2}.*”).matcher(dateStr).matches()){
fm = “yyyy-MM-dd”;
}elseif(Pattern.compile(“^[0-9]{4}-[0-9]{1}-[0-9]+.*||^[0-9]{4}-[0-9]+-[0-9]{1}.*”).matcher(dateStr).matches()){
fm = “yyyy-M-d”;
}else if(Pattern.compile(“^[0-9]{2}-[0-9]{2}-[0-9]{2}.*”).matcher(dateStr).matches()){
fm = “yy-MM-dd”;
}elseif(Pattern.compile(“^[0-9]{2}-[0-9]{1}-[0-9]+.*||^[0-9]{2}-[0-9]+-[0-9]{1}.*”).matcher(dateStr).matches()){
fm = “yy-M-d”;
}
//確定時間格式
if(Pattern.compile(“.*[ ][0-9]{2}”).matcher(dateStr).matches()){
fm+= ” HH”;
}else if(Pattern.compile(“.*[ ][0-9]{2}:[0-9]{2}”).matcher(dateStr).matches()){
fm+= ” HH:mm”;
}else if(Pattern.compile(“.*[ ][0-9]{2}:[0-9]{2}:[0-9]{2}”).matcher(dateStr).matches()){
fm+= ” HH:mm:ss”;
}else if(Pattern.compile(“.*[ ][0-9]{2}:[0-9]{2}:[0-9]{2}:[0-9]{0,3}”).matcher(dateStr).matches()){
fm+= ” HH:mm:ss:sss”;
}
if(!“”.equals(fm)){
try {
date = new SimpleDateFormat(fm).parse(dateStr);
} catch (ParseException e) {
throw new FrameworkException(“參數字符串“”+dateStr+“”無法被轉換爲日期格式!”);
}
}
}
}
return date;
}
}
第二步:寫一個基礎Controller,然後全部Controller都繼承這個基礎Controller就可以解決問題,代碼如下:
import java.util.Date;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import com.tl.core.spring.MyCustomDateEditor;
/**
* 所有controller的父類
*/
public class BaseController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new MyCustomDateEditor());
}
}