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 ...
随机推荐
- POJ 1182 食物链(经典并查集) (多组输入有时乱加也会错!)
多组输入有时乱加也会错! 这次用多组输入竟然,不用竟然对了,所以以后做题目,若是答案错误,先看加上或者删掉多组输入,看对不对 食物链 Time Limit: 1000MS Memory Lim ...
- open的正确使用
open一个对象的时候,不确定他是图片还是文本啊 #----------------------- import io with open('photo.jpg', 'rb') as inf: ...
- 关于JQuery.form.js异步上传文件点滴
好久没动代码了,前几天朋友委托我帮忙给做几个页面,其中有个注册带图片上传的页面.已之前的经验应该很快就能搞定,没想到的是搞了前后近一天时间.下面就说说异步上传的重要几个点,希望自己下次遇到此类问题的时 ...
- SpringBoot启动原理
SpringBoot启动原理 我们开发任何一个Spring Boot项目,都会用到如下的启动类: @SpringBootApplication public class Application { p ...
- Java基础语法(总结篇)
关键字&标识符 关键字的概念与特征 概念:Java关键字是事先定义好的对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名.方法名.类名.包名和 ...
- Vector和Arrarlist的异同;Hashtanle和HashMap的异同
Vector和ArrayList的异同 实现原理相同,功能相同,可以互用 主要区别: Vector线程安全,ArrayList重速度,轻安全,线程非安全. 长度需要增长时,Vector默认增长一倍,A ...
- Winform中实现ZedGraph的多条Y轴(附源码下载)
场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...
- <%@ include %>导入的文件乱码
如: <% String ss = (String) session.getAttribute("username"); if (ss == null || ss == &q ...
- JDK13,不如温习下Java8
JDK13于9月17号正式GA,版本新特性可参考: https://www.oschina.net/news/109934/jdk-13-released 虽然JDK更新迅速,但开发者貌似并不买账,据 ...
- linux 操作系统级别监控 vmstat/dstat 命令
vmstat命令综合了CPU.进程.内存.磁盘IO等信息 命令:vmstat 1 表示vmstat每2秒采集数据,一直采集,直到我结束程序 vmstat 2 1 表示每个两秒采集一次 ...