简述使用hibernate-validator做参数校验

117 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

背景

作为一个严谨的后端,怎么能不做入参的校验!

一般来说前端客户端一定是会做数据校验的,但是顶不住有些人偷懒不做校验啊,或者做的参数校验不严谨,那数据打到后台,就可能发生意想不到的错误,所以这时候后端也要背锅,所以,作为一个有追求的搬砖人,数据校验必然不可少。

然而传统的参数校验需要在业务代码里做if/else,不仅复杂而且侵入性太强,可读性差,就是一个一无是处的方案,今天咱们使用hibernate-validator来做参数校验。

步骤

1、引入hibernate-validator依赖

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.17.Final</version>
</dependency>

2、编写接口入参实体

public class UserAddParam extends BaseParam {

    @NotBlank(message = "客户号不能为空")
    private String custNo;
    
    @NotBlank(message = "手机号码不能为空")
    private String userPhone;

    public String getCustNo() {
        return custNo;
    }

    public void setCustNo(String custNo) {
        this.custNo = custNo;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

}

当前这里校验的注解可以有很多种策略,大家可以一一去尝试

image.png

3、在接口方法入参里加上@Valid注解

@ApiOperation(value = "新增用户")
@PostMapping(value = "/userLogin")
public ResultModel userLogin(@RequestBody @Valid UserAddParam userAddParam){
    try{
        UserInfo userInfo = userInfoService.userLogin(userAddParam);
        return ResultModel.success(userInfo);
    }catch (Exception e){
        logger.error("新增用户失败", e);
        return ResultModel.fail("新增用户失败");
    }
}

这时候咱们调用接口如果没有按照入参中各个字段的规则来传入,这个时候就会有一个MethodArgumentNotValidException异常抛出来,但是咱们要的不是异常,要的是将入参字段上标注的message信息返回给调用端。这个时候我们只需要在全局异常那里捕获这个类型的异常,然后再去除message信息封装好返回给前端就万事大吉了。

4、捕获异常,返回msg信息

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    public static final String PARAM_VALID_MSG = "字段不合法";

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    public ResultModel handle(Exception e){
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException validException = (MethodArgumentNotValidException) e;
            List<ObjectError> allErrors = validException.getBindingResult().getAllErrors();
            String validMsg = PARAM_VALID_MSG;
            if(!allErrors.isEmpty()) {
                validMsg = allErrors.get(0).getDefaultMessage();
            }
            return ResultModel.fail(HttpStatus.HTTP_NOT_ACCEPTABLE, validMsg);
        } else {
            logger.error("系统异常", e);
            return ResultModel.fail();
        }
    }

}

总结

虽然这个功能是完成了,用起来也很方便,感叹用别人造的的轮子真的爽,自己轻轻松松就实现了一个难题,我用都用了,但是仍然不明白它实现的原理是什么,为什么几个注解就能搞定了呢?真相是什么?真想有空好好看看源码了。自己太废了。