SpringBoot2.x系列教程21--WebBindingInitializer对请求参数实现全局校验

简介: 前言在上一章节中,我给大家讲解了WebDataBinder的含义及其用法,并实现了对请求参数的合法性校验和数据绑定。接下来我会为大家讲解另一个进行参数校验的类WebBindingInitializer,进而实现一个全局的数据绑定和参数校验。在SpringMVC中使用WebBindingInitializer,会为每个特殊的请求初始化一个相应的WebDataBinder,WebBindingInitializer是可以实现全局级别的实现方案,区别于@InitBinder只对单个Controller有效。一. WebBindingInitializer简介在使用SpringMVC的时候,

前言

在上一章节中,我给大家讲解了WebDataBinder的含义及其用法,并实现了对请求参数的合法性校验和数据绑定。接下来我会为大家讲解另一个进行参数校验的类WebBindingInitializer,进而实现一个全局的数据绑定和参数校验。

在SpringMVC中使用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时间戳,单位为秒,类似默认是String类型,而Java后端用的是Date类型。那么在进行request请求时,如何把前端的时间戳类型优雅的转换为后端的Date类型呢?

我们在之前利用@InitBinder实现过这个需求,但是@InitBinder只能对当前Controller有效,无法做到对项目中的所有Controller都有效,那么如何实现全局的参数类型转换呢?这就需要WebBindingInitializer来实现了。

2. 创建web项目(略)

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

3. 创建实体类OrderForm

我们首先创建一个“com.yyg.boot.domain”项目包,在该包下面首先创建一个OrderForm实体类。

packagecom.yyg.boot.domain;
importlombok.Data;
importlombok.ToString;
importjava.util.Date;
/*** @Description Description* @Author 一一哥Sun* @Date Created in 2020/3/24*/@Data@ToStringpublicclassOrderForm {
privateStringid;
privateStringuserName;
privateDateaddTime;
}

4. 创建自定义的PropertyEditorSupport

然后再创建一个“com.yyg.boot.bind”项目包,在该包下面首先创建一个自定义的PropertyEditorSupport类,该类会帮助我们解决前后端传参时时间类型转换的问题。

packagecom.yyg.boot.bind;
importjava.beans.PropertyEditorSupport;
importjava.util.Date;
importjava.util.concurrent.TimeUnit;
/*** @Description 扩展类型转换* @Author 一一哥Sun* @Date Created in 2020/3/24*/publicclassMyCustomDateEditorextendsPropertyEditorSupport {
/*** @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)* 前端传入的是unix时间戳,也就是long型,然后后台接收到前端传入的这个参数时会先被转换为String类型,* 默认情况下,是不能将String转为Date类型的,所以我们再这里将String字符串变为Date类型!*/@OverridepublicvoidsetAsText(Stringtext) throwsIllegalArgumentException {
setValue(newDate(Long.decode(text)));
    }
/*** @see java.beans.PropertyEditorSupport#getAsText()* 后台给前端返回响应信息,也要处理Date类型,将Date类型转为String.*/@OverridepublicStringgetAsText() {
Datevalue= (Date) getValue();
return (value!=null?String.valueOf(TimeUnit.MILLISECONDS.toSeconds(value.getTime())) : "");
    }
}

5. 创建WebBindingInitializer

然后在“com.yyg.boot.bind”项目包下创建一个自定义的WebBindingInitializer类,扩展Web初始化的配置,WebBindingInitializer可以实现全局属性编辑器的配置。

packagecom.yyg.boot.bind;
importorg.springframework.beans.propertyeditors.CustomDateEditor;
importorg.springframework.web.bind.WebDataBinder;
importorg.springframework.web.bind.support.WebBindingInitializer;
importjava.util.Date;
/*** @Description 扩展web初始化的配置,WebBindingInitializer实现全局属性编辑器配置* @Author 一一哥Sun* @Date Created in 2020/3/24*/publicclassCustomDateWebBindingInitializerimplementsWebBindingInitializer {
@OverridepublicvoidinitBinder(WebDataBinderbinder) {
binder.registerCustomEditor(Date.class, newMyCustomDateEditor());
    }
}

6. 注册WebBindingInitializer

然后在“com.yyg.boot.bind”项目包下创建CustomDateEditorConfiguration类,把WebBindingInitializer注册到RequestMappingHandlerAdapter中,让配置在request请求时生效。

packagecom.yyg.boot.bind;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
/*** @Description 让配置在request请求时生效* @Author 一一哥Sun* @Date Created in 2020/3/24*/@ConfigurationpublicclassCustomDateEditorConfiguration {
@AutowiredpublicvoidsetWebBindingInitializer(RequestMappingHandlerAdapterrequestMappingHandlerAdapter) {
//将自定义的CustomDateWebBindingInitializer属性编辑器绑定到RequestMappingHandlerAdapter里面.requestMappingHandlerAdapter.setWebBindingInitializer(newCustomDateWebBindingInitializer());
    }
}

7. 编写Controller测试方法

我们创建Controller类,在该类中创建一个测试方法,验证我们的全局属性编辑器。

@PostMapping(value="/order")
publicStringorder(@Valid@RequestBodyOrderFormform,BindingResultbindingResult) {
if (bindingResult.hasErrors()) {
returnbindingResult.getFieldError().getDefaultMessage();
    }
log.warn("order={}",form.toString());
return"success";
}

8. 代码结构

最终的代码结构如下图所示:

9. 启动项目进行测试

我们利用Postman,在Postman中输入http://localhost:8080/order地址,传入json格式的参数:

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

其中addTime是unix的时间戳字符串。

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

结语

至此,我们就实现了全局的属性编辑器,这样以后就不用在每一个Controller都利用@InitBinder进行独立的日期格式化了。

今日小作业:

实现自己的全局日期参数格式化转换。

目录
打赏
0
0
0
0
16
分享
相关文章
|
8月前
|
springBoot 使用 @NotEmpty,@NotBlank,@NotNull 及@Valid注解校验请求参数
springBoot 使用 @NotEmpty,@NotBlank,@NotNull 及@Valid注解校验请求参数
337 7
|
9月前
|
springboot自定义拦截器,校验token
springboot自定义拦截器,校验token
537 6
|
9月前
|
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
144 5
SpringBoot参数校验@Validated、@Valid(javax.validation)详解
SpringBoot参数校验@Validated、@Valid(javax.validation)
1163 4
Spring Boot中的 6 种API请求参数读取方式
本文介绍了Spring Boot中6种常见的请求参数读取方式:@RequestParam用于加载URL查询参数,@PathVariable处理RESTful风格的URL路径参数,@MatrixVariable处理URL路径中的矩阵变量,@RequestBody用于读取POST/PUT请求的复杂请求体,@RequestHeader加载请求头信息,而@CookieValue则用于获取Cookie值。这些注解在不同场景下满足了API参数的多样化需求。
116 6
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
Spring Boot实现各种参数校验
这些是Spring Boot中实现参数校验的一些常见方法,你可以根据项目需求选择适合的方式来进行参数校验。
73 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等