接口参数校验之@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也提供了这部分 ...
随机推荐
- jmeter之集合点的使用
通过jmeter并不能1秒立即达到某一并发,这时候,可以通过集合点来实现,达到某一并发时,然后再一起执行某一动作,仅作用于第一次动作的时候 目录 1.集合点元件 2.简单的概念介绍 1.集合点元件 集 ...
- Kestrel web server implementation in ASP.NET Core
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore1x&view ...
- canvas绘制随机颜色的柱形图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- python time 和日期相关模块
时间日期相关的模块 calendar 日历模块 time 时间模块 datetime 日期时间模块 timeit 时间检测模块 日历模块 calendar() 功能:获取指定年份的日历字符串 格式:c ...
- Learning OSG programing---Multi Camera in Multi window 在多窗口中创建多相机
这个例子演示了在多个窗口中创建多个相机,函数的代码如下: void multiWindowMultipleCameras(osgViewer::Viewer& viewer,bool mult ...
- CSS选择器,优先级的总结
CSS选择器 css选择器种类 基本选择器: 通配符选择器 * id选择器 #id 类选择器 .className 元素选择器 E 元素后代选择器 E F 子元素选择器 E > F 相邻兄弟元 ...
- Flutter 仿滴滴出行App
绿色出行 Flutter 仿滴滴出行App 地图:采用高德地图,仅简单完成了部分功能,基础地图,地址检索,逆地理编码. 界面:仿滴滴主界面,地图中心请求动效果,服务tabs展开效果,地址检索界面,城市 ...
- mybatis问题整理
// List<String> findBuildByProject(String prjName); //单参数时使用<if></if>标签判断采用"_ ...
- [HDU 1529]Cashier Employment(差分约束系统)
[HDU 1529]Cashier Employment(差分约束系统) 题面 有一个超市,在24小时对员工都有一定需求量,表示为\(r_i\),意思为在i这个时间至少要有i个员工,现在有n个员工来应 ...
- P3515 [POI2011]Lightning Conductor(决策单调性分治)
P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下 ...