(四)Spring Boot配合Hibernate Validator参数校验

参照:https://www.cnblogs.com/yihuihui/p/11656053.html


一、参数校验依赖的引入

当我们创建了一个springboot项目,引入了 spring-boot-web-starter 依赖之后,我们 就可以使用 参数校验了。

因为 web-starter 中已经默认的引入了 hibernate validator 参数校验功能了。
在这里插入图片描述

二、数据校验的使用场景?

场景: 当我们需要校验的参数个数较多时,我们可以把这些参数 封装到一个VO类中,然后在 对每个属性进行参数校验。

好处 :这样会使得 我们的代码看起来非常简洁,而且搭配 全局异常处理 之后,会有更好的效果。

三、 校验类型都有哪些?

参考:


###空检查###

@Null       参数值必须为null,否则校验失败,抛异常。

@NotNull    参数值必须 不能为null。无法查检长度为0的字符串。

@NotEmpty   String的话:值不能为 `null` 和 不能是空字符串 "".
			Collection的话:值 不能为null 和 size != 0@NotBlank   String的话:值不能为 `null` 、 不能空字符串 "" 、不能是空格字符串"   "。
			【注】:此注解只对字符串有效,并且会自动的去掉字符串的前后空格.




**Booelan检查**

@AssertTrue     Boolean值必须为 true  

@AssertFalse    Boolean值必须为 true   false  

 
 

**长度检查**

@Size(min=, max=, message="元素个数必须在5-20之间") 
验证对象(Array,Collection,Map,String)长度 必须在指定的范围之内  

@Length(min=5, max=20, message="用户名长度必须在5-20之间")  

 

**日期检查**

@Past       验证 Date 和 Calendar 对象是否在当前时间之前  

@Future     验证 Date 和 Calendar 对象是否在当前时间之后  

@Pattern    String值 必须否符合正则表达式的规则




**数值检查,**
建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为String为"",Integer为null

@Min            Number 和 String 值不能小于 给定值  

@Max            Number 和 String 值不能大于 给定值 

@DecimalMax 	被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.
				小数存在精度

@DecimalMin 	被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.
				小数存在精度

@Digits     	验证 Number 和 String 的构成是否合法  

@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。



@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.

@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;

 


**@Valid 递归的对关联对象进行校验**, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)




@CreditCardNumber信用卡验证

@Email  验证是否是邮件地址,如果为null,不进行验证,算通过验证。

@ScriptAssert(lang= ,script=, alias=)

@URL(protocol=,host=, port=,regexp=, flags=)

四、如何使用:

1、在实体类中的属性上 添加 需要的校验规则注解:
如:
@Email (message=" ") ,message属性的意思是:数值校验失败时的提示信息。
代码如下:

@Data
public class UserVO  {

    @NotBlank(message = "not null")
    private String name;

    @Email(message = "format is not")
    private String email;
}

2、然后在 VO使用的地方,使用@Validated注解,来开启数据格式校验。

如在Controller代码的入参上:

/**
     * 使用了@RequestBody 注解接收参数
     *
     * 校验失败,抛出异常:MethodArgumentNotValidException
     *
     * @param person
     * @return
     */
    @RequestMapping("/valid1")
    public Object test1(@RequestBody @Validated Person person, BindingResult bindingResult) {
        //参数校验
        if (bindingResult.hasErrors()) {
        	// 抛出一个自定义类型的异常,然后用全局处理器 统一补货来处理。
            throw new ParamException(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        return person;
    }

    /**
     * 未使用@RequestBody 注解接收参数
     *
     * 校验失败,抛出异常:BindException  BeanPropertyBindingResult
     *
     * @param person
     * @param bindingResult 校验的结果对象
     * @return
     */
    @RequestMapping("/valid2")
    public Object test2(@Validated Person person, BindingResult bindingResult) {
    	//参数校验
        if (bindingResult.hasErrors()) {
        	// 抛出一个自定义类型的异常,然后用全局处理器 统一补货来处理。
            throw new ParamException(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        return person;
    }

五、校验失败时的异常 情况分类:

  • 当使用@RequestBody 接收 json 格式数据时,数据校验失败时,就会抛出异常:MethodArgumentNotValidException

  • 若未用 @RequestBody 的形式直接接收参数时,校验失败,则会抛出 BindException e 这个类型的异常。

异常的处理:
异常被抛出后,一般是使用 全局异常处理 的方式,来进行统一的异常捕获处理。然后响应给前端 提示信息。

@ControllerAdvice
public class GlobalException {

/**
 * MethodArgumentNotValidException 异常处理
 * 产生原因:使用@RequestBody 注解的参数校验失败。
 *  
 * @param e MethodArgumentNotValidException 
 * @return FebsResponse
 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public String MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        StringBuilder message = new StringBuilder();
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        for (FieldError error : fieldErrors) {
            message.append(error.getField()).append(error.getDefaultMessage()).append(",");
        }
        message = new StringBuilder(message.substring(0, message.length() - 1));
        return "MethodArgumentNotValidException " + message.toString();
    }


/**
 * BindException 异常处理
 * 产生原因:对象类型的参数绑定失败(即:未使用@RequestBody 注解的参数校验)
 * 
 * @param e BindException
 * @return FebsResponse
 */
	@ExceptionHandler(BindException.class)
    @ResponseBody
    public String validExceptionHandler(BindException e) {
        StringBuilder message = new StringBuilder();
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        for (FieldError error : fieldErrors) {
            message.append(error.getField()).append(error.getDefaultMessage()).append(",");
        }
        message = new StringBuilder(message.substring(0, message.length() - 1));
        return "BindException : " + message.toString();
    }

	/**
		自定义的异常类型ParamException,来捕获以上 两种不同类的参数校验异常类型。
	*/
	@ExceptionHandler(value = ParamException.class)
    @ResponseBody
    public void paramException(ParamException ex, WebRequest request, HttpServletResponse response) throws IOException {
        //利用HttpServletResponse返回 特定http状态码
        RespDataUtil.buildBizError(response, ExceptionCodeEnum.USER_REQUEST_PARAMETER_ERROR.getErrorCode(), ex.getMessage());
        logger.error("参数异常信息 ex={}", ex.getMessage(), ex);

        return;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值