接口参数校验之@Valid与BindingResult
接口方法往往需要对入参做一些校验,从而判断入参是否合格,而javax.validation包为我们提供了一些常用的参数校验注解,使用起来很方便。
下面这个示例是检验入参对象中的password是否为空
1. 创建一个User.java
import javax.validation.constraints.NotBlank;
public class User {
private String username;
@NotBlank
private String password;
private Integer age;
}
2. 接口方法
@PostMapping("/user")
public User createUser(@Valid @RequestBody User user) {
System.out.println(user);
user.setAge(100);
return user;
}
3. 测试代码
@Test
public void testCreateUser() throws Exception {
String jsonUser = "{\"username\":\"admin\",\"password\":null}";
mockMvc.perform(MockMvcRequestBuilders.post("/user")
.contentType(MediaType.APPLICATION_JSON)
.content(jsonUser))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.age").value("100"));
}
4. 测试结果

在测试代码中, 我们的password=null, 所以检验不通过,报400。而password不为null ,测试通过,如下

5. BindingResult
在以上的参数校验中,如果参数校验不通过,都不通进入接口方法,我们也不好收集错误信息.。 不过,spring为我们提供了一个java类BindingResult.java, 借助它即可!
注意: @Valid与BindingResult要配套使用
5.1 接口代码
@PostMapping("/user")
public User createUser(@Valid @RequestBody User user, BindingResult errors) {
if (errors.hasErrors()) {
errors.getAllErrors().stream().forEach(x-> System.out.println(x.getDefaultMessage()));
}
System.out.println(user);
user.setAge(100);
return user;
}
5.2 测试代码及打印结果

5.3 自定义错误信息
public class User {
private String username;
@NotBlank(message = "密码不能为空")
private String password;
private Integer age;
}

6. 自定义注解
javax.validation默认提供了不少的注解,但是有时候,我们需要按照自己的逻辑去自定义注解。
下面举个例子,在创建User对象时,先校验一下数据库是否存在相同的用户名username, 代码如下:
6.1 查询逻辑
@Service
public class UserService { /**
* 模拟查询,检验admin用户名是否存在
* @param username
* @return
*/
public boolean findUserByUsername(String username) {
if (StringUtils.equals(username, "admin")) {
return false;
}
return true; }
}
6.2 自定义注解及实现
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
// 该注解的具体实例逻辑类
@Constraint(validatedBy = MyValidatorImpl.class)
public @interface MyValidator {
String message() default "admin用户已存在"; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { };
}
import org.springframework.beans.factory.annotation.Autowired;
import qinfeng.zheng.mockmvcdemo.service.UserService; import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext; /**
* 实现 ConstraintValidator接口的类,spring会将其弄成一个bean
*/
public class MyValidatorImpl implements ConstraintValidator<MyValidator, String> {
@Autowired
private UserService userService; @Override
public void initialize(MyValidator anno) {
System.out.println("初始化。。。。");
} /**
* @param value 需要校验的参数值
* @param constraintValidatorContext
* @return false : 校验不通过
* true : 校验通过
*/
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
return userService.findUserByUsername(value);
}
}
6.3 实体类上注解的使用
public class User {
@MyValidator
private String username;
@NotBlank(message = "密码不能为空")
private String password;
private Integer age;
}
6.4 校验接口
@PostMapping("/user")
public User createUser(@Valid @RequestBody User user, BindingResult errors) {
if (errors.hasErrors()) {
errors.getAllErrors().stream().forEach(x-> System.out.println(x.getDefaultMessage()));
}
System.out.println(user);
user.setAge(100);
return user;
}
6.5 测试代码


接口参数校验之@Valid与BindingResult的更多相关文章
- Spring Boot 之:接口参数校验
Spring Boot 之:接口参数校验,学习资料 网址 SpringBoot(八) JSR-303 数据验证(写的比较好) https://qq343509740.gitee.io/2018/07/ ...
- Spring Boot实现通用的接口参数校验
Spring Boot实现通用的接口参数校验 Harries Blog™ 2018-05-10 2418 阅读 http ACE Spring App API https AOP apache IDE ...
- SpringBoot实现通用的接口参数校验
本文介绍基于Spring Boot和JDK8编写一个AOP,结合自定义注解实现通用的接口参数校验. 缘由 目前参数校验常用的方法是在实体类上添加注解,但对于不同的方法,所应用的校验规则也是不一样的,例 ...
- springboot 接口参数校验
前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...
- 【快学springboot】4.接口参数校验
前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...
- 接口参数校验(不使用hibernate-validator,规避大量if else)
引言 编写接口时,常用的参数校验使用hibernate-validator注解+@@Validated注解进行参数校验.当遇到一些特殊场景或需求,需要自己对参数进行手动校验时,会出现以下问题: 不可避 ...
- Spring Boot 参数校验
1.背景介绍 开发过程中,后台的参数校验是必不可少的,所以经常会看到类似下面这样的代码 这样写并没有什么错,还挺工整的,只是看起来不是很优雅而已. 接下来,用Validation来改写这段 2.Spr ...
- Springboot学习06-Spring AOP封装接口自定义校验
Springboot学习06-Spring AOP封装接口自定义校验 关键字 BindingResult.Spring AOP.自定义注解.自定义异常处理.ConstraintValidator 前言 ...
- springboot 参数校验详解
https://www.jianshu.com/p/89a675b7c900 在日常开发写rest接口时,接口参数校验这一部分是必须的,但是如果全部用代码去做,显得十分麻烦,spring也提供了这部分 ...
随机推荐
- videojs实践--兼容ie7,8
1,还是先上图 ie9+,ff,chrome,,,
- IBatis.Net 下使用SqlBulkCopy 大批量导入数据 问题解决
SQLBulkCopy是继承SQLClient空间下的一个特殊类,它可以帮助我们以映射的方式把DataTable和DataReader数据大批量导入到数据库对应表中 public void Inert ...
- 1208C Magic Grid
题目大意 给你一个n 让你用0~n^2-1的数填满一个n*n的正方形 满足每个数值出现一次且每行每列的异或值相等 输出任意一种方案 分析 我们发现对于4*4的正方形 0 1 2 3 4 5 ...
- P1040加分二叉树
据说窝回去的那几天考了n次试 过去了一个月才想起来补锅 传送 首先来区分一下什么是中序遍历,什么又是前序遍历 中序遍历:左,根,右(也就是说给出一个序列(按照中序遍历的序列),第i个点左边的点都是i的 ...
- docker 部署 tomcat
1.搜索tomcat信息 docker search tomcat 2.下拉tomcat 镜像 docker pull tomcat 3.运行tomcat docker run -d --name=t ...
- 002-序列化装换JSON&XML概述
一.概述 https://github.com/bjlhx15/java-serializer java-serializer 序列化项目 serialize-json-lib:json-lib框架 ...
- Windows 下手工搭建 LNMP 环境
参考资料 如果想方便,可以直接使用集成的 LNMP 环境(例如 PHPStudy). 下载 PHP 下载地址:https://windows.php.net/download 根据你的系统选择 32 ...
- ab工具进行压力测试
简介与安装 ab:Apache Benchmark,只要我们安装了Apache,就能够在Apache的安装目录中找到它. yum | apt 安装的Apache ab的目录一般为/usr/bin 也 ...
- Altium Designer chapter3总结
绘制电路原理图中需要注意的如下: (1)元件库的操作:元件库的加载和卸载.查找元件. (2)元件操作: 1.放置元件(元件库中,place part,快捷键)中place part中的history可 ...
- POJ - 3176 Cow Bowling 动态规划
动态规划:多阶段决策问题,每步求解的问题是后面阶段问题求解的子问题,每步决策将依赖于以前步骤的决策结果.(可以用于组合优化问题) 优化原则:一个最优决策序列的任何子序列本身一定是相当于子序列初始和结束 ...