抑郁症健康,内容丰富有趣,生活中的好帮手!
抑郁症健康 > Springbootg整合validation整合

Springbootg整合validation整合

时间:2021-03-07 23:44:59

相关推荐

坚持年年写博客,不能断了,所以粘贴平时写的一份笔记吧

一、简介

校验参数在以前基本都是使用大量的if/else,稍微方便一点的可以使用反射+自定义注解的形式,但是复用性不是很好,并且每个人对于的自定义注解有着自己的使用习惯,不过好在spring开发了validated框架用于注解校验,可以节省很多的校验ifelse代码。

@PostMapping("/save")public Object save(@RequestBody User user) {String mobile = userVO.getMobile();//手动逐个 参数校验~ 写法if (StringUtils.isBlank(mobile)) {return R.bulid(ResultEnum.PARAM_FAIL_CODE,"mobile:手机号码不能为空");} else if (!Pattern.matches("^[1][3,4,5,6,7,8,9][0-9]{9}$", mobile)) {return R.bulid(ResultEnum.PARAM_FAIL_CODE,"mobile:手机号码格式不对");}//抛出自定义异常等~写法if (StringUtils.isBlank(userVO.getUsername())) {throw new ParamException(ResultEnum.PARAM_FAIL_CODE, "用户名不能为空");}// 比如写一个map返回if (StringUtils.isBlank(userVO.getSex())) {Map<String, Object> result = new HashMap<>(5);result.put("code", Constant.PARAM_FAIL_CODE);result.put("msg", "性别不能为空");return result;}//.........各种写法 ...userService.save(user);return R.success();}

二、Spring Validation

spring Validation是一种参数检验工具,集成在spring-context包中, 常用于spring mvcController的参数处理,主要针对整个实体类的多个可选域进行判定,对于不合格的数据信息springMVC会把它保存在错误对象中,这些错误信息我们也可以通过SpringMVC提供的标签或者前端的脚本等在前端页面上进行展示。

1、实现方式

实现方式和使用方式:一般使用较多的是两个注解:@Validated@Valid

@Valid和@Validated 两种注释都会导致应用标准Bean验证。

如果验证不通过会抛出BindException异常,并变成400(BAD_REQUEST)响应;

或者可以通过Errors或BindingResult参数在控制器内本地处理验证错误。

如果参数前有@RequestBody注解,验证错误会抛出MethodArgumentNotValidException异常。

2、Java Bean Validation

JSR是Java Specification Requests的缩写,意思是Java 规范提案。关于数据校验这块,最新的是JSR380,也就是我们常说的Bean Validation 2.0。

Bean Validation 2.0 是JSR第380号标准。该标准连接如下:The Java Community Process(SM) Program - Community Update - View Community Update Information for JSR# 380

Bean Validation的主页:Jakarta Bean Validation - Home

Bean Validation的参考实现:/hibernate/hibernate-validator

Bean Validation是一个通过配置注解来验证参数的框架,它包含两部分Bean Validation API(规范)和Hibernate Validator(实现)。

Bean Validation是Java定义的一套基于注解/xml的数据校验规范,目前已经从JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于.08),已经经历了三个版本

3、@Valid@Validated区别

可以理解成@Validated是@Valid升级版

Spring最终是调用Hibernate Validator执行校验,Spring Validation只是做了一层封装。

通过源码分析:

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Valid {}​@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Validated {Class<?>[] value() default {};}

@Valid:没有分组的功能。

@Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上

@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制

@Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上

关于分组功能,此处我们不涉及,有兴趣的同学可以自己研究一下

3、常用注解

validator-api-2.0的约束注解有22个,具体我们看下面表格

空与非空检查

@NotNull:适用于基本数据类型(Integer,Long,Double等等),当 @NotNull 注解被使用在 String 类型的数据上,则表示该数据不能为 Null(但是可以为 Empty,即双引号空) @NotBlank:适用于 String 类型的数据上,加了@NotBlank 注解的参数不能为 Null 且 trim() 之后 size > 0 @NotEmpty:适用于 String、Collection集合、Map、数组等等,加了@NotEmpty 注解的参数不能为 Null 或者 长度为 0

Boolean值检查

日期检查

数值检查

其他

hibernate-validator扩展约束(部分)

综合在一起,对于不同的api版本可能出现部分注解过时等情况,注意!

三、通过BindingResult处理错误信息

使用Validator,利用BindingResult获取Errors信息

1、pom引入依赖

只需要spring-boot-starter-validation和web即可

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- validation --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>

2、修改实体类User

package com.woniuxy.ssm.entity;​import java.io.Serializable;import java.util.Date;​import com.fasterxml.jackson.annotation.JsonFormat;import lombok.Data;import org.hibernate.validator.constraints.Length;import org.hibernate.validator.constraints.Range;import org.springframework.format.annotation.DateTimeFormat;​import javax.validation.constraints.NotBlank;import javax.validation.constraints.NotNull;import javax.validation.constraints.Pattern;import javax.validation.constraints.Size;​/*** * @TableName user*/@Datapublic class User implements Serializable {/*** */private Integer id;​/*** 用户名*/@NotBlank(message = "用户名不能为空")@Length(message = "用户名长度不能超过{max}个字符",max = 10)private String userName;​/*** 电话*/@Pattern(regexp = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$",message = "手机号码有误!")private String tel;/*** 密码*/@NotBlank(message = "密码不能为空")@Size(message = "密码不小于{min}位", min= 8)private String password;/*** 年龄*/@NotNull(message = "请输入年龄")@Range(message = "年龄范围为 {min} 到 {max} 之间", min = 1, max = 100)private Integer age;​/*** */@DateTimeFormat(pattern = "yyyy-MM-dd")@JsonFormat(pattern = "yyyy-MM-dd" ,timezone = "GMT+8")private Date createDate;​/*** */private String headImg;​/*** */private Integer deptId;​private static final long serialVersionUID = 1L;}

3、修改UserController中的add方法

得到所有错误中的第一个返回给用户显示,第一个并不一定是固定的,如果密码长度和年龄同时不满足,多次查询返回的结果并不是固定的,且不会超过这两个错误信息

/*** @Description TODO* @Valid 表示对这个对象校验* @param user* @param bindingResult 获取的是校验的结果,这个对象有许多方法获取校验信息,可以自定义返回信息* @Return com.woniuxy.ssm.util.Result* @Author fengSir* @Date Create by -06-12 14:58*/@PostMapping("addDo")public Result add(@Valid @RequestBody User user, BindingResult bindingResult){if(bindingResult.hasErrors()){return Result.error(bindingResult.getFieldError().getDefaultMessage());}int result = userService.insertSelective(user);return Result.ok();}

我们也可以@Valid换成@Validated,两者效果相同

4、通过测试工具类测试

三、使用全局异常处理错误信息

虽然使用bindingResult可以解决校验问题,但代码侵入性太强。此时我们可以考虑采用全局异常来解决

1、改造UserController中的add方法

@PostMapping("addDo")public Result add(@Validated @RequestBody User user){int result = userService.insertSelective(user);return Result.ok();}

2、通过测试工具测试

由于参数里有@RequestBody注解,验证错误会抛出MethodArgumentNotValidException异常

3、自定义全局异常

package com.woniuxy.ssm.exception;​import org.springframework.validation.BindException;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;​/*** @author :fengSir* @date :Created By -06-12 16:12* @description :TODO*/@RestControllerAdvicepublic class ValidExceptionHandler {​@ExceptionHandler(BindException.class)public Result validExceptionHandler(BindException exception) {return Result.error(exception.getBindingResult().getFieldError().getDefaultMessage());}​}

4、再次测试

得到和以前一样的测试结果

四、@Valid 和 @Validated 比较

对 @Valid 和 @Validated 两个注解进行总结下:

@Valid 和 @Validated 两者都可以对数据进行校验,待校验字段上打的规则注解(@NotNull, @NotEmpty等)都可以对 @Valid 和 @Validated 生效;

@Valid 进行校验的时候,需要用 BindingResult 来做一个校验结果接收。当校验不通过的时候,如果手动不 return ,则并不会阻止程序的执行;

@Validated 进行校验的时候,也可以用 BindingResult 来做一个校验结果接收。当校验不通过的时候,程序会抛出400异常,阻止方法中的代码执行,这时需要再写一个全局校验异常捕获处理类,然后返回校验提示。

总体来说,@Validated 使用起来要比 @Valid 方便一些,它可以帮我们节省一定的代码,并且使得方法看上去更加的简洁。

如果觉得《Springbootg整合validation整合》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。