spring boot参数验证
必须要知道
- 简述 JSR303/JSR-349,hibernate validation,spring validation 之间的关系
JSR303 是一项标准,JSR-349 是其的升级版本,添加了一些新特性,他们规定一些校验规范即校验注解,如 @Null,@NotNull,@Pattern,他们位于 javax.validation.constraints 包下,只提供规范不提供实现;
hibernate validation 是对这个规范的实践,他提供了相应的实现,并增加了一些其他校验注解,如 @Email,@Length,@Range 等等,他们位于 org.hibernate.validator.constraints 包下;
spring validation,是对 hibernate validation 进行了二次封装,在 springmvc 模块中添加了自动校验,并将校验信息封装进了特定的类中;
spring mvc对spring validation的应用
get请求 参数验证
@RestController
@RequestMapping("/beavalidate")
public class BeanValidateController {
@GetMapping("/testget")
public ResultBody testGet(@Valid @NotBlank @RequestParam("name") String name){
return ResultBody.successBody("get方式验证成功!");
}
}
post请求 参数验证
@RestController
@RequestMapping("/beavalidate")
public class BeanValidateController {
@PostMapping("/testpost")
public ResultBody testPost(@Valid @RequestBody TagAddForm tagAddForm){
return ResultBody.successBody("验证成功!");
}
}
参数验证异常统一处理
如果我们没有对验证错误进行处理,调用接口的客户端无法知道到底是什么参数发生了错误,
还有就是如果前后端分离我们一般都是规定json格式传输数据,所以我们最好针对这个错误进行处理并返回格式化的内容。
定义错误相关的枚举
public interface IResult extends Serializable {
Integer getCode();
String getMessage();
}
public enum ResultEnum implements IResult {
/**
* 成功
*/
SUCCESS(10000, "成功"),
/**
* 请求参数异常
*/
ARGUMENT_EXCEPTION(10001, "请求信息异常");
private Integer code;
private String message;
ResultEnum(Integer code, String msg) {
this.code = code;
this.message = msg;
}
@Override
public Integer getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
定义统一的json对象
@Data
public class ResultBody<T> {
/**
* 错误码
*/
private Integer code;
/**
* 提示信息
*/
private String message;
/**
* 具体数据
*/
private T body;
private ResultBody() {
}
/**
* 构造成功包体
*
* @return 成功的包体
*/
public static ResultBody successBody() {
return dowith(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage(), new HashMap<>(1));
}
/**
* 构造成功的包体
*
* @param body 包体中body的内容
* @return 成功的包体
*/
public static ResultBody successBody(Object body) {
return dowith(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMessage(), body);
}
/**
* 构造调用失败的包体
*
* @param result 错误码和提示信息内容
* @return 失败的包体
*/
public static ResultBody errorBody(IResult result) {
return dowith(result.getCode(), result.getMessage(), new HashMap<>(1));
}
/**
* 构造调用失败的包体
*
* @param result 错误码和提示信息内容
* @param body 包体内容
* @return 失败的包体
*/
public static ResultBody errorBody(IResult result, Object body) {
return dowith(result.getCode(), result.getMessage(), body);
}
/**
* 构造调用失败的包体
*
* @param result 错误码和提示信息内容
* @return 失败的包体
*/
public static ResultBody errorBody(IResult result, String message) {
return dowith(result.getCode(), message, null);
}
/**
* 构造调用失败的包体
*
* @param result 错误码和提示信息内容
* @param body 包体内容
* @return 失败的包体
*/
public static ResultBody errorBody(IResult result, Object body, String message) {
return dowith(result.getCode(), message, body);
}
}
定义异常处理器
@ControllerAdvice
public class ValidationExceptionHandler {
/**
* 处理post方式参数验证异常
* @param e
* @return
*/
@ExceptionHandler({MethodArgumentNotValidException.class})
@ResponseBody
public ResultBody notValidException(MethodArgumentNotValidException e) {
log.error("API参数校验异常:{}", e);
return this.wrapperBindingResult(e.getBindingResult());
}
/**
* 处理get方式参数验证异常
* @param e
* @return
*/
@ResponseBody
@ExceptionHandler({MissingServletRequestParameterException.class})
public ResultBody requestMissingParamsErrorHandler(MissingServletRequestParameterException e) {
log.error("MissingServletRequestParameterException:{}", e);
String errorMessage = e.getMessage();
ResultEnum resultEnum = ResultEnum.ARGUMENT_EXCEPTION;
return ResultBody.errorBody(resultEnum);
}
private ResultBody wrapperBindingResult(BindingResult bindingResult) {
ResultEnum resultEnum = ResultEnum.ARGUMENT_EXCEPTION;
StringBuilder errorMessage = new StringBuilder();
if ("prod".equals(this.profile)) {
errorMessage.append("请求信息异常");
} else {
Iterator var4 = bindingResult.getFieldErrors().iterator();
while(var4.hasNext()) {
FieldError fieldError = (FieldError)var4.next();
errorMessage.append(fieldError.getField()).append(fieldError.getDefaultMessage()).append(";");
}
}
resultEnum.setMessage(errorMessage.toString());
return ResultBody.errorBody(resultEnum);
}
}
效果
get方式参数验证

post方式参数验证:

非mvc环境下使用验证
在一些情况下我们并不是只是验证http请求参数的绑定,我们还需要java方法之间调用的参数验证。
不适用验证框架我们一般都是手动验证,但是手动验证是很费力的,下面就介绍一下在非mvc的情况下使用spring validation框架进行验证。
手动验证
定义bean添加验证注解
@Data
public class TagAddForm {
@NotEmpty(message = "标签名称不能为空")
private String name;
@Min(value = 1,message = "标签类型不能为空")
private int type;
}
编写手动验证逻辑
@Component
public class TagValidate {
/**
* 验证bean的参数
* <p>
* 手动验证
* </p>
*/
public void validateBean(){
TagAddForm tagAddForm=new TagAddForm();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<TagAddForm>> violations = validator.validate(tagAddForm);
//为空代表验证通过
if (violations.size()==0){
return;
}
for(ConstraintViolation<TagAddForm> violation: violations) {
System.out.println((violation.getMessage()));
}
}
}
单元测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestValidate {
@Autowired
private TagValidate tagValidate;
@Autowired
private UserValidate userValidate;
@Test
public void test(){
tagValidate.validateBean();
}
}
结果:

自动验证
业务类编写
在类上添加注解:@Validated 在方法上添加:@Valid注解
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
@Validated
@Component
public class UserValidate {
public void add(@Valid TagAddForm tagAddForm){
System.out.println("添加标签");
}
}
测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestValidate {
@Autowired
private UserValidate userValidate;
@Test
public void test2(){
//new一个 TagAddForm对象作为参数并没有为其赋值
TagAddForm tagAddForm=new TagAddForm();
userValidate.add(tagAddForm);
}
}
结果

spring boot参数验证的更多相关文章
- spring boot 参数传递(spring boot 参数传数 arg0 每一个参数 arg0#{arg0},arg1 #{arg1})
spring boot 参数传数 arg0 每一个参数 arg0#{arg0},arg1 #{arg1} @Select("select * from sys_user where nam ...
- Spring Boot 参数校验
1.背景介绍 开发过程中,后台的参数校验是必不可少的,所以经常会看到类似下面这样的代码 这样写并没有什么错,还挺工整的,只是看起来不是很优雅而已. 接下来,用Validation来改写这段 2.Spr ...
- Spring Boot系列(四) Spring Boot 之验证
这节没有高深的东西, 但有一些学习思路值得借鉴. JSR 303 (Bean Validation) Maven依赖 <dependency> <groupId>org.spr ...
- Spring Boot参数校验
1. 概述 作为接口服务提供方,非常有必要在项目中加入参数校验,比如字段非空,字段长度限制,邮箱格式验证等等,数据校验常用到概念:JSR303/JSR-349: JSR303是一项标准,只提供规范不提 ...
- Validated 注解完成 Spring Boot 参数校验
1. @Valid 和 @Validated @Valid 注解,是 Bean Validation 所定义,可以添加在普通方法.构造方法.方法参数.方法返回.成员变量上,表示它们需要进行约束校验. ...
- Spring Boot 微信-验证服务器有效性【转】
转:https://blog.csdn.net/jeikerxiao/article/details/68064145 概述 接入微信公众平台开发,开发者需要按照如下步骤完成: 在自己服务器上,开发验 ...
- 记一次spring boot参数初始化的问题
背景:接手一个项目,看到一个配置参数的引用: @Value("${webSocket.id}") 再看看配置application.yml: ... webSocket: id: ...
- Spring boot 参数相关注解
最近使用swagger的在线文档调试接口时发现老是报参数问题,最后发现是方法中参数上的注解有问题,今天把填的坑做一下总结. 1. RequestParam 该注解有两个属性: name/value:表 ...
- spring Boot登录验证之验证码 邮箱
一 验证码 登录login.jsp <%@ page contentType="text/html;charset=UTF-8" language="java&qu ...
随机推荐
- codeforces 735C. Tennis Championship(贪心)
题目链接 http://codeforces.com/contest/735/problem/C 题意:给你一个数n表示有几个人比赛问最多能赢几局,要求两个比赛的人得分不能相差超过1即得分为2的只能和 ...
- 模板汇总——快读 fread
struct FastIO { ; int wpos; char wbuf[S]; FastIO() : wpos() { } inline int xchar() { static char buf ...
- android CTS 介绍
[转]http://blog.csdn.net/pugongying1988/article/details/6976091 一.为什么需要兼容性测试(以下称CTS)? 1.1.让APP提供更好的用户 ...
- NameNode数据存储
HDFS架构图 HDFS原理 1) 三大组件 NameNode. DataNode .SecondaryNameNode 2)NameNode 存储元数据(文件名.创建时间.大小.权限.文件与blo ...
- Salesforce LWC学习(七) Navigation & Toast
上一篇我们介绍了针对LWC中常用的LDS的适配的wire service以及@salesforce模块提供的相关的service,其实LWC中还提供其他的好用的service,比如针对导航相关的lig ...
- 《Java 8 in Action》Chapter 10:用Optional取代null
1965年,英国一位名为Tony Hoare的计算机科学家在设计ALGOL W语言时提出了null引用的想法.ALGOL W是第一批在堆上分配记录的类型语言之一.Hoare选择null引用这种方式,& ...
- Linux 笔记 - 第八章 文档的打包与压缩
博客地址:http://www.moonxy.com 一.前言 在 Linux 系统中,文件的后缀名没有实际的意义,加或者不加都无所谓.但是为了便于区分,我们习惯在定义文件名时加一个后缀名,比如常见的 ...
- 当 K8s 集群达到万级规模,阿里巴巴如何解决系统各组件性能问题?
作者 | 阿里云容器平台高级技术专家 曾凡松(逐灵) 本文主要介绍阿里巴巴在大规模生产环境中落地 Kubernetes 的过程中,在集群规模上遇到的典型问题以及对应的解决方案,内容包含对 etcd.k ...
- Spring框架学习笔记(2)——面向切面编程AOP
介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...
- MyEclipse中的web项目之前有个感叹号
java web项目有感叹号说明导入的jar包存在问题 或者环境配置不正确 解决办法是点击项目-->Build path -->configure Build Path 然后来到Libra ...