前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【原创】002 | 搭上SpringBoot实战专车系列二:Web应用参数校验

【原创】002 | 搭上SpringBoot实战专车系列二:Web应用参数校验

作者头像
java进阶架构师
发布2021-02-22 14:30:57
3100
发布2021-02-22 14:30:57
举报
文章被收录于专栏:Java进阶架构师Java进阶架构师

专车介绍

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

专车问题

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

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

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

专车实战

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

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

代码语言:javascript
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

第三步:创建启动类

代码语言:javascript
复制
@SpringBootApplication
public class ValidateApplication {

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

第四步:创建控制器

代码语言:javascript
复制
@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();
    }
}

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

第五步:创建实体类

代码语言:javascript
复制
@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;
}

第六步:发送请求

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

输入错误的请求参数:

代码语言:javascript
复制
{
	"id":null,
	"name":"",
	"email":"a563830372"
}

响应结果:

代码语言:javascript
复制
[name.not.empty, id.not.empty, email.invalid]

输入正确的请求参数:

代码语言:javascript
复制
{
	"id":100001,
	"name":"test",
	"email":"a563830372@163.com"
}

响应结果:

代码语言:javascript
复制
[]

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

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

代码语言:javascript
复制
@Data
public class Student {

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

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

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

代码语言:javascript
复制
@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中某个属性不符合校验规则也需要报错,那么事实是怎样的呢?

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

请求参数:

代码语言:javascript
复制
{
	"id":100001,
	"name":"test",
	"email":"a563830372@163.com",
	"studentList":[{
		"id":null,
		"name":""
	}]
}

响应结果:

代码语言:javascript
复制
[]

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

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

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

请求参数:

代码语言:javascript
复制
{
	"id":100001,
	"name":"test",
	"email":"a563830372@163.com",
	"studentList":[{
		"id":null,
		"name":""
	}]
}

响应结果:

代码语言:javascript
复制
[student.d.not.empty, student.name.not.empty]

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

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

第一步:添加国际化配置

代码语言:javascript
复制
@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;
    }
}

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

英文配置:messages_en_US.properties

代码语言:javascript
复制
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

中文配置:messages_en_US.properties

代码语言:javascript
复制
id.not.empty=老师编号不能为空
name.not.empty=老师姓名不能为空
email.not.empty=老师邮箱不能为空
email.invalid=请提供合法的邮箱地址
student.id.not.empty=学生编号不能为空
student.name.not.empty=学生名称不能为空

第三步:修改实体类

代码语言:javascript
复制
@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;
}
代码语言:javascript
复制
@Data
public class Student {

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

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

第四步:发送请求

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

请求参数:

代码语言:javascript
复制
{
	"id":null,
	"name":"",
	"email":"a563830372163.com",
	"studentList":[{
		"id":null,
		"name":""
	}]
}

响应结果:

代码语言:javascript
复制
[姓名不能为空, 请提供合法的邮箱地址, 学生名称不能为空, 编号不能为空, 学生编号不能为空]

第五步:切换成英语

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

请求参数:

代码语言:javascript
复制
{
	"id":null,
	"name":"",
	"email":"a563830372163.com",
	"studentList":[{
		"id":null,
		"name":""
	}]
}

响应j结果:

代码语言:javascript
复制
[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]

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

专车总结

实现参数校验:

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

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

实现集合对象的校验:

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

实现国际化:

第一步:添加国际化配置

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

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

专车地址

[Spring Boot Web应用参数校验](https://github.com/a601942905git/boot-example/tree/master/boot-example-validate)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java进阶架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 专车介绍
  • 专车问题
  • 专车实战
  • 专车总结
  • 专车地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档