SpringBoot2.x系列教程31--整合SpringMVC之处理请求参数的绑定(三)WebBindingInitializer

SpringBoot2.x系列教程31--整合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项目(略)

我们继续在上一章节的案例中,进行代码实现。

SpringBoot2.x系列教程31--整合SpringMVC之处理请求参数的绑定(三)WebBindingInitializer_第1张图片

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时间戳。

SpringBoot2.x系列教程31--整合SpringMVC之处理请求参数的绑定(三)WebBindingInitializer_第2张图片

我们在web后台进行了日志打印,可以看到unix时间戳被成功的转换成了Date类型

SpringBoot2.x系列教程31--整合SpringMVC之处理请求参数的绑定(三)WebBindingInitializer_第3张图片

至此,我们实现了全局的属性编辑器。

你可能感兴趣的:(Spring,Boot,2,SpringBoot)