估计很多朋友都认为参数校验是客户端的职责,不关服务端的事。其实这是错误的,学过 Web 安全的都知道,客户端的验证只是第一道关卡。它的参数验证并不是安全的,一旦被有心人抓到可乘之机,他就可以有各种方法来摸拟系统的 Http 请求,访问数据库的关键数据。轻则导致服务器宕机,重则泄露数据。所以,这时就需要设置第二道关卡,服务端验证了。

老项目的服务端校验

  1. @RestController
  2. @RequestMapping("/student")
  3. public class ValidateOneController {
  4. @GetMapping("/id")
  5. public Student findStudentById(Integer id){
  6. if(id == null){
  7. logger.error("id 不能为空!");
  8. throw new NullPointerException("id 不能为空");
  9. }
  10. return studentService.findStudentById(id);
  11. }
  12. }

看以上代码,就一个的校验就如此麻烦。那我们是否有好的统一校验方法呢?鉴于 SpringBoot 无所不能。答案当然是有的。

其中,Bean Validator 和 Hibernate Validator 就是两套用于验证的框架,二者都遵循 JSR-303 ,可以混着用,鉴于二者的某些 Validator 注解有差别,例如 @Length 在 Bean Validator 中是没有的,所以这里我选择混合用。

JSR-303

JSR-303 是JAVA EE 6 中的一项子规范,叫做 Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现, Hibernate Validator 提供了 JSR 303 规范中所有内置 Constraint(约束) 的实现,除此之外还有一些附加的 Constraint 。这些 Constraint (约束) 全都通过注解的方式实现,请看下面两个表。

Bean Validation 中内置的约束:

注解 作用
@Null 被注解参数必须为空
@NotNull 被注解参数不能为空
@AssertTrue 被注解参数必须为 True
@AssertFalse 被注解参数必须为 False
@Min(value) 被注解参数必须是数字,且其值必须大于等于 value
@Max(value) 被注解参数必须是数字,且其值必须小于等于 value
@DecimaMin(value) 被注解参数必须是数字,且其值必须大于等于 value
@DecimaMax(value) 被注解参数必须是数字,且其值必须小于等于 value
@Size(max, min) 被注解参数大小必须在指定范围内
@Past 被注解参数必须是一个过去的日期
@Future 被注解参数必须是一个将来的日期
@Pattern(value) 被注解参数必须符合指定的正则表达式
@Digits(integer, fraction) 被注解参数必须是数字,且其值必须在可接受范围内
@NotBlank 被注解参数的值不为空(不为 null、去除首位空格后长度为 0),不同于 @NotEmpty,@NotBlank 只应用于字符串且在比较时会去除字符串的空格

Hibernate Validator 附加的约束:

注解 作用
@NotEmpty 被注解参数的值不为 null 且不为空(字符串长度不为0、集合大小不为0)
@Email 被注解参数必须是电子邮箱地址
@Length 被注解的字符串长度必须在指定范围内
@Range 被注解的参数必须在指定范围内

准备工作

  • SpringBoot 2.1.3
  • IDEA
  • JDK8

Pom 文件依赖

  1. <!-- web 启动类 -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <!-- test 单元测试类 -->
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-test</artifactId>
  10. <scope>test</scope>
  11. </dependency>
  12. <!-- lombok 依赖用于简化 bean -->
  13. <dependency>
  14. <groupId>org.projectlombok</groupId>
  15. <artifactId>lombok</artifactId>
  16. <optional>true</optional>
  17. </dependency>

实体类

用于测试,加入了参数校验规则。

  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class Student {
  5. private Integer id;
  6. @NotBlank(message = "学生名字不能为空")
  7. @Length(min = 2, max = 10, message = "name 长度必须在 {min} - {max} 之间")
  8. private String name;
  9. @NotNull(message = "年龄不允许为空")
  10. @Min(value = 0, message = "年龄不能低于 {value} 岁")
  11. private Integer age;
  12. }

Controller 层

写了两个方法,一个用于校验普通参数,一个用于校验对象

  1. @Validated //开启数据校验,添加在类上用于校验方法,添加在方法参数中用于校验参数对象。(添加在方法上无效)
  2. @RestController
  3. @RequestMapping("/student")
  4. public class ValidateOneController {
  5. /**
  6. * 普通参数校验
  7. * @param name
  8. * @return
  9. */
  10. @GetMapping("/name")
  11. public String findStudentByName(@NotBlank(message = "学生名字不能为空")
  12. @Length(min = 2, max = 10, message = "name 长度必须在 {min} - {max} 之间")String name){
  13. return "success";
  14. }
  15. /**
  16. * 对象校验
  17. * @param student
  18. * @return
  19. */
  20. @PostMapping("/add")
  21. public String addStudent(@Validated @RequestBody Student student){
  22. return "success";
  23. }
  24. }

Postman 测试

校验普通参数测试结果:

下图可以看见,我没有在 http://localhost:8080/student/name 地址后添加 name 参数,传到后台马上就校验出异常了。而这个异常信息就是我定义的校验异常信息。

校验对象测试结果:

结果有点长:

下图可以看见,我访问 http://localhost:8080/student/add 传入了参数对象,但对象是不能通过校验规则的,比如 age 参数为负数,name 参数长度太大,传到后台马上就校验出异常了。而这个异常信息就是我定义的校验异常信息。

完整代码

https://github.com/turoDog/Demo/tree/master/springboot_validateone_demo

如果觉得对你有帮助,请给个 Star 再走呗,非常感谢。

最后

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「一个优秀的废人」,关注后回复「1024」送你一套完整的 java 教程。



Spring Boot2 系列教程 (十五) | 服务端参数校验之一的更多相关文章

  1. Spring Boot2 系列教程(十五)定义系统启动任务的两种方式

    在 Servlet/Jsp 项目中,如果涉及到系统任务,例如在项目启动阶段要做一些数据初始化操作,这些操作有一个共同的特点,只在项目启动时进行,以后都不再执行,这里,容易想到web基础中的三大组件( ...

  2. Spring Boot2 系列教程(十)Spring Boot 整合 Freemarker

    今天来聊聊 Spring Boot 整合 Freemarker. Freemarker 简介 这是一个相当老牌的开源的免费的模版引擎.通过 Freemarker 模版,我们可以将数据渲染成 HTML ...

  3. Spring Boot2 系列教程(十四)CORS 解决跨域问题

    今天和小伙伴们来聊一聊通过CORS解决跨域问题. 同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由 Netsca ...

  4. Spring Boot2 系列教程 (十六) | 整合 WebSocket 实现广播

    前言 如题,今天介绍的是 SpringBoot 整合 WebSocket 实现广播消息. 什么是 WebSocket ? WebSocket 为浏览器和服务器提供了双工异步通信的功能,即浏览器可以向服 ...

  5. Spring Boot2 系列教程(十二)@ControllerAdvice 的三种使用场景

    严格来说,本文并不算是 Spring Boot 中的知识点,但是很多学过 SpringMVC 的小伙伴,对于 @ControllerAdvice 却并不熟悉,Spring Boot 和 SpringM ...

  6. Spring Boot2 系列教程(十六)定时任务的两种实现方式

    在 Spring + SpringMVC 环境中,一般来说,要实现定时任务,我们有两中方案,一种是使用 Spring 自带的定时任务处理器 @Scheduled 注解,另一种就是使用第三方框架 Qua ...

  7. Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置

    用过 Spring Boot 的小伙伴都知道,我们只需要在项目中引入 spring-boot-starter-web 依赖,SpringMVC 的一整套东西就会自动给我们配置好,但是,真实的项目环境比 ...

  8. Spring Boot2 系列教程(十九)Spring Boot 整合 JdbcTemplate

    在 Java 领域,数据持久化有几个常见的方案,有 Spring 自带的 JdbcTemplate .有 MyBatis,还有 JPA,在这些方案中,最简单的就是 Spring 自带的 JdbcTem ...

  9. Spring Boot2 系列教程 (十八) | 整合 MongoDB

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 如题,今天介绍下 SpringBoot 是如何整合 MongoDB 的. MongoDB 简介 MongoDB 是由 C++ ...

随机推荐

  1. Python--day31--黏包(不熟...)

  2. Python3 dir() 函数

    Python dir() 函数 描述 dir() 函数不带参数时,返回当前范围内的变量.方法和定义的类型列表:带参数时,返回参数的属性.方法列表.如果参数包含方法__dir__(),该方法将被调用.如 ...

  3. Spring Cloud探路(二) Erueka客户端的建立

    接上篇 1.pom.xml与上篇一致 2.新建包及Application启动类 @Configuration @ComponentScan @EnableEurekaClient @EnableAut ...

  4. win10下,cmd,power shell设置默认编码为‘UTF-8’?

    这个问题可以终结了,最新版 Windows 10 支持 UTF-8 了.打开这个选项,cmd 和 powershell 默认就是 UTF-8 了.在控制面板-时钟和区域-区域-管理-更改系统区域设置( ...

  5. LR性能测试自动化集成JENKINS

    LR11不支持JENKINS集成,解决方案可以使用BAT代替执行,JENKINS定时调用BAT执行性能测试用例.   1. 先随便录制l一个LR脚本,保存为 D:\TEST\test01 2. 打开 ...

  6. javascript中的深拷贝与浅拷贝

    javascript中的深拷贝与浅拷贝 基础概念 在了解深拷贝与浅拷贝的时候需要先了解一些基础知识 核心知识点之 堆与栈 栈(stack)为自动分配的内存空间,它由系统自动释放: 堆(heap)则是动 ...

  7. 正则&转义字符&特殊字符

    正则 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 由于正则表达式主要应用对 ...

  8. CP防火墙升级和打补丁

    CP防火墙的升级和打补丁可以在命令行下操作,也可以在web ui下进行,CP的升级首先得升级Deployment Agent软件 Step1:升级Deployment Agent ========== ...

  9. TestStand 基本设置

    1. 过程模型设置 菜单->Configure->Station Options->Model TestStand 默认提供了三种过程模型 Sequential.Batch.Para ...

  10. Android CTS中neverallow规则生成过程

    CTS里面SELinux相关测试中neverallow测试项占绝大多数,Android系统开发者都应该知道,在修改sepolicy时,需要确保不能违反这些neverallow规则,不然会过不了CTS. ...