SpringBoot 2.0实战专车系列二:Web应用参数校验

​专车介绍

该趟专车是开往SpringBoot Web应用参数校验的实战专车,主要讲解如何对请求入参进行安全校验,防止不合法的数据进入系统。

专车问题

第一个问题:如何对请求入参进行校验

第二个问题:如何对入参对象中集合里面的对象进行参数校验

第三个问题:参数校验提示信息如何实现国际化展示

专车实战

第一步:在父模块下面新建一个名为boot-example-validate的子模块

第二步:子模块添加如下依赖

<code><dependencies>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
/<dependency>

<dependency>
<groupid>org.projectlombok/<groupid>
<artifactid>lombok/<artifactid>
/<dependency>
/<dependencies>/<code>

第三步:创建启动类

<code>@SpringBootApplication
public class ValidateApplication {

public static void main(String[] args) {
SpringApplication.run(ValidateApplication.class, args);
}
}/<code>

第四步:创建控制器

<code>@RestController
@RequestMapping("/teachers")
public class TeacherController {

@PostMapping("/add")
public String add(@RequestBody @Valid Teacher user, BindingResult bindingResult) {
List<fielderror> list = bindingResult.getFieldErrors();
List<string> messageList = new ArrayList<>();
for (FieldError fieldError : list) {
messageList.add(fieldError.getDefaultMessage());
}
return messageList.toString();
}
}/<string>/<fielderror>/<code>

可以看到与之前不同的是,在需要校验的对象前面添加了@Valid注解,该注解的功能就是用来进行数据校验的

第五步:创建实体类

<code>@Data
public class Teacher {

@NotNull(message = "id.not.empty")
private Integer id;

@NotEmpty(message = "name.not.empty")
private String name;

@NotEmpty(message = "email.not.empty")
@Email(message = "email.invalid")
private String email;
}/<code>

第六步:发送请求

http://localhost:8080/teachers/add POST

输入错误的请求参数:

<code>{
\t"id":null,
\t"name":"",

\t"email":"a563830372"
}/<code>

响应结果:

<code>[name.not.empty, id.not.empty, email.invalid]/<code>

输入正确的请求参数:

<code>{
\t"id":100001,
\t"name":"test",
\t"email":"[email protected]"
}/<code>

响应结果:

<code>[]/<code>

如上可以得出如果想要对入参数据进行校验,在需要校验的对象前面使用@Valid注解标注,然后实体对象属性上使用相应校验规则的注解

场景导入:一个老师有很多学生是很正常的一件事情,依照这个思路,我们创建一个学生实体类

<code>@Data
public class Student {

@NotNull(message = "student.d.not.empty")
private Integer id;

@NotBlank(message = "student.name.not.empty")
private String name;
}/<code>

然后在Teacher实体类中持有学生集合对象

<code>@Data
public class Teacher {


@NotNull(message = "id.not.empty")
private Integer id;

@NotEmpty(message = "name.not.empty")
private String name;

@NotEmpty(message = "email.not.empty")
@Email(message = "email.invalid")
private String email;

@NotEmpty(message = "student list can not be empty")
private List<student> studentList;
}/<student>/<code>

接下来再来试试我们的参数校验功能,我们期望的是,如果Student中某个属性不符合校验规则也需要报错,那么事实是怎样的呢?

http://localhost:8080/teachers/add POST

请求参数:

<code>{
\t"id":100001,
\t"name":"test",
\t"email":"[email protected]",
\t"studentList":[{
\t\t"id":null,
\t\t"name":""
\t}]
}/<code>

响应结果:

<code>[]/<code>

如上响应结果返回一个空数组,也就是请求的参数没有问题,是合法的请求。这种结果完全不是我们想要的,那么该如何解决此问题的出现?

解决方法也很简单,我们只需要在集合对象上加上@Valid注解就可以了,再次请求我们的程序

http://localhost:8080/teachers/add POST

请求参数:

<code>{
\t"id":100001,
\t"name":"test",
\t"email":"[email protected]",
\t"studentList":[{
\t\t"id":null,
\t\t"name":""
\t}]
}/<code>

响应结果:

<code>[student.d.not.empty, student.name.not.empty]/<code>

看到这个结果我们第二个问题就解决了,那么如何实现提示信息的国际化呢?

想要实现国际化,我们需要针对不同的国家配置不同的提示信息,然后在请求的时候携带响应的语言,解析对应文件中的key,获取我们想要的提示信息

第一步:添加国际化配置

<code>@Configuration
public class ValidateConfigure {

@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource
= new ReloadableResourceBundleMessageSource();

messageSource.setBasenames("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}

@Bean
public LocalValidatorFactoryBean getValidator() {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
}/<code>

第二步:在resources目录下添加国际化配置文件

英文配置:messages_en_US.properties

<code>id.not.empty=id can not be empty
name.not.empty=name can not be empty
email.not.empty=email can not be empty
email.invalid=please provided a valid email address
student.id.not.empty=student id can not be empty
student.name.not.empty=student name can not be empty/<code>

中文配置:messages_en_US.properties

<code>id.not.empty=老师编号不能为空
name.not.empty=老师姓名不能为空
email.not.empty=老师邮箱不能为空
email.invalid=请提供合法的邮箱地址
student.id.not.empty=学生编号不能为空
student.name.not.empty=学生名称不能为空/<code>

第三步:修改实体类

<code>@Data
public class Teacher {

@NotNull(message = "{id.not.empty}")
private Integer id;

@NotEmpty(message = "{name.not.empty}")
private String name;

@NotEmpty(message = "{email.not.empty}")
@Email(message = "{email.invalid}")
private String email;


@Valid
@NotEmpty(message = "{student.list.not.empty}")
private List<student> studentList;
}/<student>/<code>
<code>@Data
public class Student {

@NotNull(message = "{student.id.not.empty}")
private Integer id;

@NotBlank(message = "{student.name.not.empty}")
private String name;
}/<code>

第四步:发送请求

http://localhost:8080/teachers/add POST

请求参数:

<code>{
\t"id":null,
\t"name":"",
\t"email":"a563830372163.com",
\t"studentList":[{
\t\t"id":null,
\t\t"name":""
\t}]
}/<code>

响应结果:

<code>[姓名不能为空, 请提供合法的邮箱地址, 学生名称不能为空, 编号不能为空, 学生编号不能为空]/<code>

第五步:切换成英语

在请求的header中添加accept-language:en-US

请求参数:

<code>{ 

\t"id":null,
\t"name":"",
\t"email":"a563830372163.com",
\t"studentList":[{
\t\t"id":null,
\t\t"name":""
\t}]
}/<code>

响应j结果:

<code>[id can not be empty, name can not be empty, student id can not be empty, please provided a valid email address, student name can not be empty]/<code>

可以看到,想要切换语言,只需要在header中添加accept-language配置即可

专车总结

实现参数校验:

第一步:在需要校验的对象前面添加@Valid注解,其实添加@Validated也可以实现同样的功能

第二步:在实体类添加相应规则的注解,比如:@NotNull、@NotEmpty

实现集合对象的校验:

在集合对象上添加@Valid注解

实现国际化:

第一步:添加国际化配置

第二步:添加不同语言的配置文件

第三步:实体类提示信息使用{}包裹配置文件中指定的key

没别的意思,麻烦来个关注+点赞+留言+收藏。有问题的可以看我签名


分享到:


相關文章: