使用正則表達式優雅的解決 SpringMVC 時間轉換問題

1、簡述

使用SpringMVC接收過期間參數的程序員都應該知道,時間轉換是一個使人頭疼的問題,雖然這不是什麼大問題,解決的方法也有多種,但解決不妥的話感受起來會很不舒服,由於處理不當會把時間的接收格式寫死,若是開發後期想更改時間格式呢?又或者項目要求能夠接收不一樣格式的時間參數的話那又該怎麼辦呢?這時就能夠經過正則表達式來解決這種問題了。下面就來看看如何用正則表達式優雅的解決這種問題。javascript

2、全局時間轉換

一、自定義時間轉換器

/** * 日期轉換器 */
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;
    }

}複製代碼

二、註冊時間轉換器

<?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-1五、2017.02.1五、2017/02/1五、2017-02-15 14:20:55。。。java

3、局部時間轉換

局部時間轉換,就是在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。正則表達式

一、建立自定義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;
    }
}複製代碼

二、使用自定義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());
    }

}複製代碼

4、總結

這兩種方式我推薦使用第一種,由於是全局的,配置過一次以後,整個項目的時間參數均可以隨便接收,且不須要在Controller中寫任何代碼,減小代碼入侵。而第二種方式的優勢就是不用在配置文件中作任何操做,所有由代碼解決,不過是隻對當前Controller生效。總的來講,使用正則表達式能夠很好的解決多格式時間參數問題,若是項目中存在其餘的時間格式,能夠在對應的自定義時間轉換器類或自定義的DateEditor中追加正則表達式以知足項目需求。spring

相關文章
相關標籤/搜索