SpringMVC之(三)WebBindingInitializer

在上一章節中,我給大家講解了WebDataBinder的含義及其用法,接下來我會爲大家講解WebBindingInitializer,由此來實現一個全局的數據綁定。

在Spring MVC中使用WebBindingInitializer,爲每個特殊的請求初始化相應的WebDataBinder,WebBindingInitializer是可以實現全局級別的實現方案,區別於@InitBinder只對單個Controller有效。

一. WebBindingInitializer簡介

在使用SpringMVC的時候,經常會遇到表單中的日期字符串和Java Bean中的Date類型轉換的問題。而在SpringMVC中,默認是不支持這種轉換的。所以就需要我們手動配置,設計自定義的數據綁定才能解決這個問題。

而在SpringMVC中,提供了不同的類型轉換器,這些類型轉換器常用於轉換double、float、date等類型。SpringMVC在支持自身轉換器框架的同時,也支持Java Bean的PropertyEditor。

我們可以通過在控制器中使用@InitBinder 添加Controller級別的自定義類型編輯器,也可以通過WebBindingInitializer來添加全局級別(對所有@Controller有效)的自定義類型編輯器。

二. 全局級別編輯器的實現方案

1. 需求分析

假如我們現在有這麼一種情況:
前端傳入的參數中,時間單位用的是unix時間戳,單位爲秒,而java後端用的是Date類型。

在request請求時,如何把前端的時間戳類型優雅的轉換爲後端的Date類型呢?

2. 創建web項目(略)

我們繼續在上一章節的案例中,進行代碼實現。

3. 創建實體類OrderForm

我們首先創建一個“com.yyg.boot.domain”項目包,在該包下面首先創建一個OrderForm實體類。

package com.yyg.boot.domain;

import lombok.Data;
import lombok.ToString;

import java.util.Date;

/**
 * @Description Description
 * @Author 一一哥Sun
 * @Date Created in 2020/3/24
 */
@Data
@ToString
public class OrderForm {

    private String id;

    private String userName;

    private Date addTime;

}

4. 創建自定義的PropertyEditorSupport

然後再創建一個“com.yyg.boot.bind”項目包,在該包下面首先創建一個自定義的PropertyEditorSupport類。

該類會幫助我們解決前後端傳參時時間類型轉換的問題。

package com.yyg.boot.bind;

import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @Description 擴展類型轉換
 * @Author 一一哥Sun
 * @Date Created in 2020/3/24
 */
public class MyCustomDateEditor extends PropertyEditorSupport {

    /**
     * @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
     * 前端傳入的是unix時間戳,也就是long型,然後後臺接收到前端傳入的這個參數時會先被轉換爲String類型,
     * 默認情況下,是不能將String轉爲Date類型的,所以我們再這裏將String字符串變爲Date類型!
     */
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(new Date(Long.decode(text)));
    }

    /**
     * @see java.beans.PropertyEditorSupport#getAsText()
     * 後臺給前端返回響應信息,也要處理Date類型,將Date類型轉爲String.
     */
    @Override
    public String getAsText() {
        Date value = (Date) getValue();
        return (value != null ? String.valueOf(TimeUnit.MILLISECONDS.toSeconds(value.getTime())) : "");
    }

}

5. 創建WebBindingInitializer

然後在“com.yyg.boot.bind”項目包下創建一個自定義的WebBindingInitializer類。

擴展web初始化的配置,WebBindingInitializer實現全局屬性編輯器配置。

package com.yyg.boot.bind;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;

import java.util.Date;

/**
 * @Description 擴展web初始化的配置,WebBindingInitializer實現全局屬性編輯器配置
 * @Author 一一哥Sun
 * @Date Created in 2020/3/24
 */
public class CustomDateWebBindingInitializer implements WebBindingInitializer {

    @Override
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new MyCustomDateEditor());
    }

}

6. 註冊WebBindingInitializer

然後在“com.yyg.boot.bind”項目包下創建CustomDateEditorConfiguration類,把WebBindingInitializer註冊到RequestMappingHandlerAdapter中,讓配置在request請求時生效。

package com.yyg.boot.bind;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

/**
 * @Description 讓配置在request請求時生效
 * @Author 一一哥Sun
 * @Date Created in 2020/3/24
 */
@Configuration
public class CustomDateEditorConfiguration {

    @Autowired
    public void setWebBindingInitializer(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
        //將自定義的CustomDateWebBindingInitializer屬性編輯器綁定到RequestMappingHandlerAdapter裏面.
        requestMappingHandlerAdapter.setWebBindingInitializer(new CustomDateWebBindingInitializer());
    }

}

7. 編寫Controller測試方法

我們創建Controller類,在該類中創建一個測試方法,驗證我們的全局屬性編輯器。

@PostMapping(value = "/order")
public String order(@Valid @RequestBody OrderForm form,BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return bindingResult.getFieldError().getDefaultMessage();
    }

    log.warn("order={}",form.toString());
    return "success";
}

8. 啓動項目進行測試

我們利用postman,在postman中輸入http://localhost:8080/order地址,傳入json參數:

{
    "id":1,
    "userName":"一一哥",
    "addTime":1488264066
}

其中addTime是unix時間戳。

我們在web後臺進行了日誌打印,可以看到unix時間戳被成功的轉換成了Date類型

至此,我們實現了全局的屬性編輯器。

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