SpringBoot2.x系列教程19--利用InitBinder处理请求参数的绑定(一)

简介: 前言我们在开发项目时,前后端之间需要密切配合,才能确保项目的稳定高效。前端通过URL接口给后端传递请求参数,后端根据这些不同的请求参数返回对应的响应信息。那么在这个传参和返回响应信息的过程中,会发生什么事情呢?我们能不能在这个过程中做一些干预操作呢?比如我们要添加一个学生的年龄信息,前端传递过来一个负数作为年龄参数,这个明显不合法,那么后端能不能对这个非法的参数做出一些处理呢?所以今天 壹哥 就带大家在SpringBoot中,学习一些可以处理请求参数的技巧,确保我们的后端接口更加的安全健壮。一. SpringMVC请求参数绑定流程1. 请求参数绑定流程我们在开发的时候,经常会从ht

前言

我们在开发项目时,前后端之间需要密切配合,才能确保项目的稳定高效。前端通过URL接口给后端传递请求参数,后端根据这些不同的请求参数返回对应的响应信息。那么在这个传参和返回响应信息的过程中,会发生什么事情呢?我们能不能在这个过程中做一些干预操作呢?比如我们要添加一个学生的年龄信息,前端传递过来一个负数作为年龄参数,这个明显不合法,那么后端能不能对这个非法的参数做出一些处理呢?

所以今天 壹哥 就带大家在SpringBoot中,学习一些可以处理请求参数的技巧,确保我们的后端接口更加的安全健壮。

一. SpringMVC请求参数绑定流程

1. 请求参数绑定流程

我们在开发的时候,经常会从html,jsp等页面中将请求参数通过request对象传递到后端。可是经常会遇到这么一种情况,那就是从前端传递过来的数据参数到达后端后,还需要再把该数据参数进行适当的抽取、转换、校验等操作,进而组装成另一种格式的对象。这个转换的工作,可以由SpringMVC提供的@InitBinder注解来完成。

2. SpringMVC中请求参数的绑定

SpringMVC可以自动将request中的请求参数绑定到对象的每个property属性上,但只会把一些简单的数据类型(比如String, int, float等)绑定到对应的属性上。可是如果面对复杂对象,那就要借助PropertyEditor这个接口来完成数据的绑定了。

PropertyEditor这个接口提供了两个方法,一个方法是将String类型的值转成property对应的数据类型,另一个方法是将一个property属性转成String,如下图所示:

3. CustomDateEditor继承关系

接下来我会结合CustomDateEditor与InitBinder,给大家讲解如何对前端传递过来的日期类型参数进行格式化校验。我们先来看看CustomDateEditor类的结构关系,如下图所示:

4. 示例代码

这里我先放一段校验前端日期类型参数格式的示例代码,后面我们会利用这段代码实现对前端传入的日期参数校验的目的。

@InitBinderpublicvoidInitBinder(WebDataBinderbinder) {
//前端传入的时间格式必须是"yyyy-MM-dd"效果!DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");
CustomDateEditordateEditor=newCustomDateEditor(df, true);
binder.registerCustomEditor(Date.class, dateEditor);
}

二. @InitBinder详解

在开始今天的内容之前,我先给大家介绍一个@InitBinder注解。

1. @InitBinder注解简介

@InitBinder注解可以作用在@Controller的方法上,表示为当前控制器注册一个属性编辑器,对WebDataBinder进行初始化,且只对当前的Controller有效。

2. @InitBinder执行时机

@InitBinder注解被解析的时机,是在其所位于的方法被请求执行之前。同时@InitBinder标注的方法是可以多次执行的,也就是说来一次请求就会执行一次@InitBinder解析。

3. @InitBinder执行原理

当某个Controller上的第一次请求,由SpringMVC前端控制器匹配到该Controller之后,根据Controller的 class类型来查找所有标注了@InitBinder注解的方法,并且存入RequestMappingHandlerAdapter里的 initBinderCache 缓存中。等下一次请求执行对应业务方法之前,会先走initBinderCache缓存,而不用再去解析@InitBinder。

三. @InitBinder实现过程

接下来我们编写一个案例,实现对前端传递过来的日期参数进行格式化校验。

首先我们来创建一个Web程序,创建过程请参考之前的案例,此处略!

1. 创建Controller测试接口

在创建的Web项目中,我创建一个Controller接口,接口方法中可以接受Date类型的参数。

packagecom.yyg.boot.web;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.beans.propertyeditors.CustomDateEditor;
importorg.springframework.beans.propertyeditors.StringTrimmerEditor;
importorg.springframework.stereotype.Component;
importorg.springframework.web.bind.WebDataBinder;
importorg.springframework.web.bind.annotation.*;
importorg.springframework.web.bind.support.WebBindingInitializer;
importorg.springframework.web.context.request.WebRequest;
importjava.text.DateFormat;
importjava.text.ParseException;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.HashMap;
importjava.util.Map;
/*** @Description Description* @Author 一一哥Sun* @Date Created in 2020/3/23*/@Slf4j@RestControllerpublicclassBindController {
@GetMapping(value="/bind")
publicMap<String, Object>getFormatData(Datedate) throwsParseException {
log.warn("date={}", date);
Map<String, Object>map=newHashMap<>();
map.put("name", "一一哥");
map.put("age", 30);
map.put("date", date);
returnmap;
    }
}

项目入口类的创建这里我也直接略过了,大家自行创建即可。

2. 启动程序进行测试

启动项目后,此时我们可以在Postman中输入如下地址进行测试:
http://localhost:8080/bind?date=2020-09-09

Postman中的效果如下所示:

经过测试,发现此时产生400状态码,我们知道产生400状态码的原因是前后端参数不一致,具体就是无法将前端传递过来的String类型的时间字符串转换为Date类型!因为前端是没有Date类型的,前端传递的日期参数只能被理解为String类型,默认情况下是不能把这个String类型的日期数据直接转换为Date类型的。

那怎么解决这个问题呢?

3. 添加@InitBinder代码

接下来我们在上面创建的Controller里面,添加一段新的代码,如下:

/*** @InitBinder标注的方法,只针对当前Controller有效!* 如果没有该方法,则会产生400状态码!* MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date!*/@InitBinderpublicvoidInitBinder(WebDataBinderbinder) {
//前端传入的时间格式必须是"yyyy-MM-dd"效果!DateFormatdf=newSimpleDateFormat("yyyy-MM-dd");
CustomDateEditordateEditor=newCustomDateEditor(df, true);
binder.registerCustomEditor(Date.class, dateEditor);
    }

此时完整的Controller类如下图所示:

4. 重启项目进行测试

添加完代码之后,我们把项目重启,然后我们在Postman中重新输入如下地址:
http://localhost:8080/bind?date=2020-09-09

Postman的测试效果如下:

可以发现此时前端传递的时间字符串被成功的传递到后端,并且被成功的转换成了Date类型!以上就是@InitBinder的原理及用法!

注意:

@InitBinder属于Controller级别的属性编辑器,并不是全局级别(针对所有@Controller)的属性编辑器,也就是一个@InitBinder只对当前所在的Controller有效,对其他Controller是无效的!那如果我们的项目中,有多个Controller中都要进行日期格式转换怎么办呢?请先思考一下。

5. 项目结构图

最终代码结构如下图所示,各位可以参考创建。

结语

这样我们就实现了对前端参数的校验转换效果,也就是一小段代码即可搞定,你学会了吗?

今日小作业:

思考如何实现全局的日期参数格式化校验。

目录
打赏
0
0
0
0
16
分享
相关文章
|
10月前
|
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
633 2
深入理解Spring Boot配置绑定及其实战应用
【4月更文挑战第10天】本文详细探讨了Spring Boot中配置绑定的核心概念,并结合实战示例,展示了如何在项目中有效地使用这些技术来管理和绑定配置属性。
122 1
|
8月前
|
springBoot 使用 @NotEmpty,@NotBlank,@NotNull 及@Valid注解校验请求参数
springBoot 使用 @NotEmpty,@NotBlank,@NotNull 及@Valid注解校验请求参数
337 7
Spring Boot中的 6 种API请求参数读取方式
本文介绍了Spring Boot中6种常见的请求参数读取方式:@RequestParam用于加载URL查询参数,@PathVariable处理RESTful风格的URL路径参数,@MatrixVariable处理URL路径中的矩阵变量,@RequestBody用于读取POST/PUT请求的复杂请求体,@RequestHeader加载请求头信息,而@CookieValue则用于获取Cookie值。这些注解在不同场景下满足了API参数的多样化需求。
116 6
|
10月前
|
干货文:SpringBoot 配置 AOP 打印请求参数和返回参数
干货文:SpringBoot 配置 AOP 打印请求参数和返回参数
777 1
SpringBoot后端接口请求参数映射方式详解
SpringBoot后端接口请求参数映射方式详解
914 0
Vue+Axios+SpringBoot后端同时接收文件和json作为请求参数
Vue+Axios+SpringBoot后端同时接收文件和json作为请求参数
490 0
SpringBoot3中的属性绑定注解和YMAL配置文件、日志
SpringBoot3中的属性绑定注解和YMAL配置文件、日志
SpringBoot 实体参数(用于请求参数比较多时使用)
SpringBoot 实体参数(用于请求参数比较多时使用)
AI助理

你好,我是AI助理

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