接口参数校验之@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也提供了这部分 ...
随机推荐
- Codeforces 86D Powerful array (莫队)
D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input standard i ...
- List of yellow pages
List of yellow pages From Wikipedia, the free encyclopedia [hide]This article has multiple issues. ...
- Vagrant 手册之多个虚拟机 multi-machine
原文地址 Vagrant 可以通过一个 Vagrantfile 定义并控制多个客户机.这就是所谓的"multi-machine"多虚拟机环境. 这些机器通常可以协同工作,或者互相关 ...
- js-判断当前页面是否在移动端打开显示的
if (/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)==false) { //该页面不是在移动端打开的, }
- Recurrent Neural Network(3):LSTM Basics and 《Inside Out》
下图是Naive RNN的Recurrent Unit示意图,可以看到,在每个时间点t,Recurrent Unit会输出一个隐藏状态ht,对ht加工提取后将产生t时刻的输出yt.而在下一个时间节点t ...
- LinkedList -链表集合
package cn.learn.collection; import java.util.LinkedList; import java.util.Queue; /* java.util.xxx A ...
- (三)Schema与数据类型优化
1.Schema schema,中文叫模式,是数据库的组织和结构 2.选择优化的数据类型 更小的通常更好:尽量使用可以正确存储数据的最小数据类型 简单就好:简单数据类型的操作通常需要更少的cpu周期. ...
- spring-第十篇之XML Schema的简化配置,p、c、util命名空间
1.p:命名空间 引入命名空间:xmlns:p="http://www.springframework.org/schema/p" 配置举例: <?xml version=& ...
- PHP实现上传文件到服务器
<?php /**************************** *** 功能:上传文件到服务器 ****************************/ session_start() ...
- form表单,登录用户,密码,按钮,提交、重置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...