持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}
}
当前这里校验的注解可以有很多种策略,大家可以一一去尝试
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();
}
}
}
总结
虽然这个功能是完成了,用起来也很方便,感叹用别人造的的轮子真的爽,自己轻轻松松就实现了一个难题,我用都用了,但是仍然不明白它实现的原理是什么,为什么几个注解就能搞定了呢?真相是什么?真想有空好好看看源码了。自己太废了。