bean validation校验方法参数_Springboot validation校验请求参数

导读

我们开发项目的时候,如何判断请求过来的参数非空,长度大小等情况,是不是在代码里面写非空判断,校验长度,如下代码。

4c329745156de4827e616234229c6911.png

非空判断代码

如果这个UserVO这个对象有10个字段都要做非空判断,那么这个代码就会变成很多且非常不优雅,那么我们就要想办法解决这个,因此spring为我们提供了validation框架,在springboot框架使用更加简单,validation框架都是已经整合到springboot中了。

新建一个springboot-validation项目

依赖包如下:

     org.springframework.boot        spring-boot-starter-parent        2.2.6.RELEASEorg.springframework.boot            spring-boot-starter-web        org.projectlombok            lombok        

新建一个ResponseVO类

该类是统一返回Json格式封装类,例如要统一返回格式:

{  "code":"200",         //状态码  "msg":"操作成功",   //消息  "data":null             //数据}

类如下:

/** * 统一响应VO */@Data@AllArgsConstructor@NoArgsConstructorpublic class ResponseVO {    /**     * 状态码     */    String code;    /**     * 状态信息     */    String msg;    /**     * 返回数据对象     */    T data;    /**     * 定义一个静态方法,返回成功状态码     * @return 响应对象     */    public static ResponseVO success(){        return new ResponseVO("200","操作成功",null);    }    /**     * 定义一个静态方法,返回失败状态码,以及指定失败信息     * @param msg 失败信息     * @return 响应对象     */    public static ResponseVO fail(String msg){        return new ResponseVO("999",msg,null);    }}

新建一个UserVO类

该类就用到了validation框架注解

import lombok.Data;import javax.validation.constraints.NotBlank;import javax.validation.constraints.NotNull;import javax.validation.constraints.Size;@Datapublic class UserVO {    @NotBlank(message = "用户名不能为空")    String userName;    @NotBlank(message = "密码不能为空")    @Size(min = 6,message = "密码长度最小六位")    String password;    @NotNull(message = "年龄不能为空")    Integer age;}

相关注解说明:

@AssertFalse

新建UserController类

@Controller@Slf4jpublic class UserController {    /**     * 新增用户对象     */    @GetMapping("addUser")    @ResponseBody    public ResponseVO addUser(@Validated UserVO userVO){        log.info("新增用户对象={}",userVO);        //返回成功状态码        return ResponseVO.success();    }}

@Validated 是必须注解,就是把UserVO对象用validation框架校验参数,当提交数据的时候,会自动校验UserVO里面属性非空注解。

新建SpringBootValidApp启动类

@SpringBootApplicationpublic class SpringBootValidApp {    public static void main(String[] args) {        SpringApplication.run(SpringBootValidApp.class,args);    }}

启动服务成功后,浏览器访问地址,设置请求参数空值测试

http://127.0.0.1:8080/addUser?userName=&password=&age=

发现控制台出现以下异常,说明校验生效了

2020-10-23 14:38:49.123  WARN 39904 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 4 errorsField error in object 'userVO' on field 'password': rejected value []; codes [NotBlank.userVO.password,NotBlank.password,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.password,password]; arguments []; default message [password]]; default message [密码不能为空]Field error in object 'userVO' on field 'password': rejected value []; codes [Size.userVO.password,Size.password,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.password,password]; arguments []; default message [password],2147483647,6]; default message [密码长度最小六位]Field error in object 'userVO' on field 'userName': rejected value []; codes [NotBlank.userVO.userName,NotBlank.userName,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.userName,userName]; arguments []; default message [userName]]; default message [用户名不能为空]Field error in object 'userVO' on field 'age': rejected value [null]; codes [NotNull.userVO.age,NotNull.age,NotNull.java.lang.Integer,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.age,age]; arguments []; default message [age]]; default message [年龄不能为空]]

浏览器页面显示错误信息

Whitelabel Error PageThis application has no explicit mapping for /error, so you are seeing this as a fallback.Fri Oct 23 14:38:49 CST 2020There was an unexpected error (type=Bad Request, status=400).Validation failed for object='userVO'. Error count: 4

现在只是看到了校验失败信息,那么如何把错误信息返回到页面当中呢?这个是我们下面要解决的问题

新建一个全局异常类

该异常类核心用到了一个注解:@RestControllerAdvice,该数据就是监听Controller类如果有异常的时候,通知一下,然后使用:@ExceptionHandler,来处理特定异常,从而根据异常对象,解析异常信息,封装成:ResponseVO,返回到客户端。

/** * 全局公共异常帮助类 */@RestControllerAdvice@Slf4jpublic class GlobalExceptionHandler {/** *  Get 非body请求 ,用BindException *  @RequestBody @Valid 用MethodArgumentNotValidException *  校验参数异常,显示输出具体字段错误列表 */@ExceptionHandler(value= {BindException.class,MethodArgumentNotValidException.class})public Object validatorbindException(Throwable e,HttpServletRequest req){String uri=req.getRequestURI();log.error("请求URI={},校验参数不通过",uri);BindingResult bindingResult=null;if(e instanceof BindException) {bindingResult=((BindException)e).getBindingResult();}else if(e instanceof MethodArgumentNotValidException) {bindingResult=((MethodArgumentNotValidException)e).getBindingResult();}StringBuilder msg=new StringBuilder("");try {if(bindingResult.hasErrors()) {List fieldErrors=bindingResult.getFieldErrors();for (FieldError fieldError:fieldErrors) {msg.append(", ").append(fieldError.getDefaultMessage());log.error("请求URI={},字段={},校验信息={}",uri,fieldError.getField(),fieldError.getDefaultMessage());}msg.deleteCharAt(0);}} catch (Throwable  tx) {log.error("转换校验参数异常",tx);}return  ResponseVO.fail(msg.toString());}}

重新启动服务,重新做以上非空访问测试,页面显示如下信息,证明异常返回页面处理成功

{  "code":"999",  "msg":" 密码长度最小六位, 用户名不能为空, 年龄不能为空, 密码不能为空",   "data":null}

测试正常数据请求

访问地址:http://127.0.0.1:8080/addUser?userName=xiaoming&password=123456&age=12
测试结果:{  "code":"200",  "msg":"操作成功",   "data":null}

总结

Sringboot validation校验请求参数,大大简化了在代码里面做非空判断,大大的提高了工作效率,即优雅又漂亮的代码,从此再也不用加班了,你Get到了吗?如果有疑问,欢迎大家讨论或者与我沟通。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值