SpringBoot 全局日期格式化(基於HttpMessageConverter) 學習目標 快速查閱 開始教程

還在爲日期格式化的問題頭痛?趕緊閱覽文章尋找答案吧!

學習目標

快速學會使用Jackson消息轉換器並實現日期的全局格式化。

快速查閱

專題閱讀:《SpringBoot 佈道系列》

源碼下載:springboot-date-format

— Hey Man,Don't forget to Star or Fork . —

開始教程

一、全局日期格式化(基於自動配置)

關於日期格式化,很多人會想到使用Jackson的自動配置:

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.timeZone: GMT+8

這種全局日期格式化固然方便,但在消息傳遞時只能解析特定的時間格式,在實際業務開展中並不那麼方便。例如某接口返回的是long類型的時間戳,顯然此時消息轉換器將拋出解析失敗的異常。

那麼有沒更好的辦法,既支持返回默認的日期格式,又支持解析複雜的日期字符串?
答案是有的,只需要重寫Jackson的消息轉換器來支持解析複雜的日期格式即可。

二、全局日期格式化(基於消息轉換器)

首先在項目引入JacksonThymeleaf等相關依賴:

       <dependency><!--Web相關依賴-->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency><!--Thymeleaf依賴-->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency><!--JSON 解析工具類-->
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency><!--XML 解析工具類-->
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <optional>true</optional>
        </dependency>

然後根據 SimpleDateFormat 來定製支持複雜日期類型解析的工具類。

    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {
        //根據實際業務支持各種複雜格式的日期字符串。
        @Override
        public Date parse(String source) {
            try {
                return super.parse(source);//支持解析指定pattern類型。
            } catch (Exception e) {
                try {
                    return new StdDateFormat().parse(source);//支持解析long類型的時間戳
                } catch (ParseException e1) {
                    throw new RuntimeException("日期格式非法:" + e);
                }
            }
        }
    };

緊接着根據使用場景,來介紹如何快速實現日期的格式化。

關於日期時間格式化的三種使用場景

(1)使用@ResponseBody返回JSON信息會用到MappingJackson2HttpMessageConverter

 @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        //設置解析JSON工具類
        ObjectMapper objectMapper = new ObjectMapper();
        //設置解析日期的工具類
        objectMapper.setDateFormat(dateFormat);
        //忽略未知屬性 防止解析報錯
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        jsonConverter.setObjectMapper(objectMapper);
        List<MediaType> list = new ArrayList<>();
        list.add(MediaType.APPLICATION_JSON_UTF8);
        jsonConverter.setSupportedMediaTypes(list);
        return jsonConverter;
    }

(2)使用@ResponseBody返回XML信息會用到MappingJackson2XmlHttpMessageConverter

  @Bean
    public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter() {
        MappingJackson2XmlHttpMessageConverter xmlConverter = new MappingJackson2XmlHttpMessageConverter();
        //設置解析XML的工具類
        XmlMapper xmlMapper = new XmlMapper();
        //設置解析日期的工具類
        xmlMapper.setDateFormat(dateFormat);
        //忽略未知屬性 防止解析報錯
        xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        xmlConverter.setObjectMapper(xmlMapper);
        return xmlConverter;
    }

(3)使用ModelAndView返回HTML頁面信息。

值得注意的是,無論上面哪種消息轉換器均無法滿足頁面日期的全局格式化,因爲th:object默認調用的日期Date的toString方法,所以在Thymemleaf頁面對日期格式化需要藉助工具類#dates

例如:<input th:value="*{#dates.format(createTime,'yyyy-MM-dd HH:mm:ss')}">

三、測試日期格式化

推薦大家下載源碼對照擼一遍,實踐是檢驗真理的唯一標準。

JAVA代碼:

/**
 * 用戶管理
 */
@RestController
public class UserController {

    /**
     * 打開主頁
     */
    @GetMapping("/")
    public ModelAndView index() {
        ModelAndView mv = new ModelAndView("user/user");
        mv.addObject("user", new User("1", "admin", "123456", new Date()));
        return mv;
    }

    /**
     * 自動根據請求來判斷返回用戶JSON或XML
     */
    @GetMapping("/user")
    public User get() {
        return new User("1", "admin", "123456", new Date());
    }

    /**
     * 返回用戶JSON
     */
    @GetMapping(value = "/user/json", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public User getJson() {
        return new User("1", "admin", "123456", new Date());
    }

    /**
     * 返回用戶XML
     */
    @GetMapping(value = "/user/xml", produces = MediaType.APPLICATION_XML_VALUE)
    public User getXml() {
        return new User("1", "admin", "123456", new Date());
    }

}

頁面代碼:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>日期格式化</title>
</head>
<body>
<h3><a th:href="@{/}">1.在頁面中對日期格式化</a></h3>
<form th:object="${user}">
    <input th:value="*{userId}" type="hidden">
    賬號:<input th:value="*{username}">
    密碼:<input th:value="*{password}" type="password">
    時間:<input th:value="*{createTime}" type="text">
</form>
<form th:object="${user}">
    賬號:<input th:value="*{username}">
    密碼:<input th:value="*{password}" type="password">
    時間:<input th:value="*{#dates.format(createTime,'yyyy-MM-dd HH:mm:ss')}">
</form>

<h3><a th:href="@{/user/json}">2.點擊獲取JSON信息</a></h3>
<h3><a th:href="@{/user/xml}">3.點擊獲取XML信息</a></h3>
</body>
</html>

啓動項目後訪問 http://localhost:8080 查看日期格式化效果:

四、小結

1、使用@ResponseBody會根據請求頭信息來智能選擇JSON/XML消息轉換器。

2、通過重寫HttpMessageConverter可以自定義消息轉換器來實現全局日期格式化。

3、採用類似yyyy-MM-dd HH:mm:ss的日期格式更符合國人的閱讀習慣,能夠提升用戶體驗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章