一、簡述
使用SpringMVC接收過時間引數的程式設計師都應該知道,時間轉換是一個令人頭疼的問題,雖然這不是什麼大問題,解決的方法也有多種,但解決不妥的話感覺起來會很不舒服,因為處理不當會把時間的接收格式寫死,如果開發後期想更改時間格式呢?又或者專案要求可以接收不同格式的時間引數的話那又該怎麼辦呢?這時就可以通過正規表示式來解決這種問題了。下面就來看看如何用正規表示式優雅的解決這種問題。
二、全域性時間轉換
1、自定義時間轉換器
/**
* 日期轉換器
*/
public class DataConverter implements Converter<String, Date> {
public Date convert(String source) {
SimpleDateFormat sdf = getSimpleDateFormat(source);
try {
Date date = sdf.parse(source);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
private SimpleDateFormat getSimpleDateFormat(String source) {
SimpleDateFormat sdf = new SimpleDateFormat();
if (Pattern.matches("^\d{4}-\d{2}-\d{2}$", source)) { // yyyy-MM-dd
sdf = new SimpleDateFormat("yyyy-MM-dd");
} else if (Pattern.matches("^\d{4}-\d{2}-\d{2} \d{2}-\d{2}-\d{2}$", source)) { // yyyy-MM-dd HH-mm-ss
sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
} else if (Pattern.matches("^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$", source)) { // yyyy-MM-dd HH:mm:ss
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else if (Pattern.matches("^\d{4}/\d{2}/\d{2}$", source)) { // yyyy/MM/dd
sdf = new SimpleDateFormat("yyyy/MM/dd");
} else if (Pattern.matches("^\d{4}/\d{2}/\d{2} \d{2}/\d{2}/\d{2}$", source)) { // yyyy/MM/dd HH/mm/ss
sdf = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss");
} else if (Pattern.matches("^\d{4}\d{2}\d{2}$", source)) { // yyyyMMdd
sdf = new SimpleDateFormat("yyyyMMdd");
} else if (Pattern.matches("^\d{4}\d{2}\d{2} \d{2}\d{2}\d{2}$", source)) { // yyyyMMdd HHmmss
sdf = new SimpleDateFormat("yyyyMMdd HHmmss");
} else if (Pattern.matches("^\d{4}\.\d{2}\.\d{2}$", source)) { // yyyy.MM.dd
sdf = new SimpleDateFormat("yyyy.MM.dd");
} else if (Pattern.matches("^\d{4}\.\d{2}\.\d{2} \d{2}\.\d{2}\.\d{2}$", source)) { // yyyy.MM.dd HH.mm.ss
sdf = new SimpleDateFormat("yyyy.MM.dd HH.mm.ss");
}else{
System.out.println("TypeMismatchException");
throw new TypeMismatchException();
}
return sdf;
}
}複製程式碼
2、註冊時間轉換器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
...
<!-- 轉換器服務工廠Bean -->
<bean id="conversion-service"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.lqr.convert.DataConverter" />
</set>
</property>
</bean>
<!-- 註冊轉化器 -->
<mvc:annotation-driven conversion-service="conversion-service" />
</beans>複製程式碼
這樣就可以接收絕大部分的時間格式了,如:2017-02-15、2017.02.15、2017/02/15、2017-02-15 14:20:55。。。
三、區域性時間轉換
區域性時間轉換,就是在Controller中使用@InitBinder註解一個引數型別為WebDataBinder的方法,通過WebDataBinder物件的registerCustomEditor()方法來解決時間轉換問題,例子如下:
@Controller
@RequestMapping("/test")
public class MyController {
@RequestMapping(value = "/register.do", method = RequestMethod.POST)
public ModelAndView register(String name, Date date) throws Exception {
ModelAndView mv = new ModelAndView();
System.out.println("name = " + name);
System.out.println("date = " + date);
mv.addObject("name", name);
mv.addObject("date", date);
mv.setViewName("/WEB-INF/jsp/welcome.jsp");
return mv;
}
@InitBinder
public void initBinder(WebDataBinder binder) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(df, true));
}
}複製程式碼
這裡的CustomDateEditor類是SpringMVC提供的,卻無法獲取日期資料,所以無法根據日期格式來建立不同的SimpleDateFormat物件,也就是說這種方式會把時間的格式寫死,解決方法,可以自定義DateEditor。
1、建立自定義DateEditor
public class MyDateEditor extends PropertiesEditor {
@Override
public void setAsText(String source) throws IllegalArgumentException {
SimpleDateFormat df = getSimpleDateFormat(source);
try {
Date date = df.parse(source);
setValue(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
private SimpleDateFormat getSimpleDateFormat(String source) {
SimpleDateFormat sdf = new SimpleDateFormat();
if (Pattern.matches("^\d{4}-\d{2}-\d{2}$", source)) { // yyyy-MM-dd
sdf = new SimpleDateFormat("yyyy-MM-dd");
} else if (Pattern.matches("^\d{4}-\d{2}-\d{2} \d{2}-\d{2}-\d{2}$", source)) { // yyyy-MM-dd HH-mm-ss
sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
} else if (Pattern.matches("^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$", source)) { // yyyy-MM-dd HH:mm:ss
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else if (Pattern.matches("^\d{4}/\d{2}/\d{2}$", source)) { // yyyy/MM/dd
sdf = new SimpleDateFormat("yyyy/MM/dd");
} else if (Pattern.matches("^\d{4}/\d{2}/\d{2} \d{2}/\d{2}/\d{2}$", source)) { // yyyy/MM/dd HH/mm/ss
sdf = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss");
} else if (Pattern.matches("^\d{4}\d{2}\d{2}$", source)) { // yyyyMMdd
sdf = new SimpleDateFormat("yyyyMMdd");
} else if (Pattern.matches("^\d{4}\d{2}\d{2} \d{2}\d{2}\d{2}$", source)) { // yyyyMMdd HHmmss
sdf = new SimpleDateFormat("yyyyMMdd HHmmss");
} else if (Pattern.matches("^\d{4}\.\d{2}\.\d{2}$", source)) { // yyyy.MM.dd
sdf = new SimpleDateFormat("yyyy.MM.dd");
} else if (Pattern.matches("^\d{4}\.\d{2}\.\d{2} \d{2}\.\d{2}\.\d{2}$", source)) { // yyyy.MM.dd HH.mm.ss
sdf = new SimpleDateFormat("yyyy.MM.dd HH.mm.ss");
}else{
System.out.println("TypeMismatchException");
throw new TypeMismatchException();
}
return sdf;
}
}複製程式碼
2、使用自定義DateEditor
@Controller
@RequestMapping("/test")
public class MyController {
@RequestMapping(value = "/register.do", method = RequestMethod.POST)
public ModelAndView register(String name, Date date) throws Exception {
ModelAndView mv = new ModelAndView();
System.out.println("name = " + name);
System.out.println("date = " + date);
mv.addObject("name", name);
mv.addObject("date", date);
mv.setViewName("/WEB-INF/jsp/welcome.jsp");
return mv;
}
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new MyDateEditor());
}
}複製程式碼
四、總結
這兩種方式我推薦使用第一種,因為是全域性的,配置過一次之後,整個專案的時間引數都可以隨便接收,且不需要在Controller中寫任何程式碼,減少程式碼入侵。而第二種方式的優點就是不用在配置檔案中做任何操作,全部由程式碼解決,不過是隻對當前Controller生效。總的來說,使用正規表示式可以很好的解決多格式時間引數問題,如果專案中存在其他的時間格式,可以在對應的自定義時間轉換器類或自定義的DateEditor中追加正規表示式以滿足專案需求。