求求你别在用if进行参数校验了!!!
创始人
2024-04-06 15:13:20
0

在日常工作开发中,难免会遇到各种各样的参数校验问题,大多数情况下我们都是在Controller层进行手动校验,但是当需要校验的参数比较多时,就会出现一大堆重复且枯燥的代码,每当出现这种情况是,想想都会头疼,例如下面这段代码。

/*** @Author: zhouzhou* @CreateTime: 2022-11-10  14:47* @Version: 1.0*/
@RestController
public class UserLoginController {@PostMappingpublic SingleResponse login(@RequestBody UserLoginReqDTO userLoginReqDTO){if (StringUtils.isEmpty(userLoginReqDTO.getUserName())){return SingleResponse.buildFailure("500","用户名不能为空");}if (StringUtils.isEmpty(userLoginReqDTO.getPassword())){return SingleResponse.buildFailure("500","密码不能为空");}if (userLoginReqDTO.getUserName().length() < 5){return SingleResponse.buildFailure("500","用户名不能小于5位");}if (userLoginReqDTO.getPassword().length() < 5){return SingleResponse.buildFailure("500","密码不能小于5位");}// 校验通过走服务层逻辑//返回结果return SingleResponse.buildSuccess();}
}

其实还有更简单优雅的办法帮我们去解决这种问题——Spring Validation。

解决方案

Spring Validation使用Java Api规范(JSR303)定义了Bean对象的校验标准。而hibernate validation对这个规范进行了实现,而Spring Validation是对 hibernate validation的再次封装,用来支持spring mvc参数的自动校验,下面我们就以spring boot项目进行代码演示。

引入依赖

因为作者使用的是spring boot 2.7.x,所以需要手动引入 hibernate validator依赖。如果版本小于2.3.x则无需手动引入


org.hibernate.validatorhibernate-validator6.1.7.Final

org.projectlomboklomboktrue

com.alibaba.colacola-component-dto4.0.1

项目实战

使用POST请求接收参数,控制层使用开头中的if进行参数校验,效果如下:

使用Spring validation进行参数校验:

1.首先在数据参数对象DTO中声明校验规则


@Data
public class UserLoginReqDTO {@NotNull(message = "用户名不能为空")@Length(min = 5) // 长度最小为5private String userName;@NotNull(message = "密码不能为空")@Length(min = 5)private String password;
}

2.在方法参数上声明校验注解 @Validated

@PostMapping("/user/login2")
public SingleResponse login2(@RequestBody @Validated UserLoginReqDTO userLoginReqDTO){System.out.println("进入login2方法-------------");// 校验通过走服务层逻辑//返回结果return SingleResponse.buildSuccess();
}

效果如下:

因为参数校验不通过,服务器抛出异常,可以在服务日志中查看到如下提示

2022-11-10 15:30:58.371  WARN 40924 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.alibaba.cola.dto.SingleResponse com.example.demojproect.controller.UserLoginController.login2(com.example.demojproect.dto.request.UserLoginReqDTO) with 2 errors: [Field error in object 'userLoginReqDTO' on field 'password': rejected value [null]; codes [NotNull.userLoginReqDTO.password,NotNull.password,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userLoginReqDTO.password,password]; arguments []; default message [password]]; default message [密码不能为空]] [Field error in object 'userLoginReqDTO' on field 'userName': rejected value [null]; codes [NotNull.userLoginReqDTO.userName,NotNull.userName,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userLoginReqDTO.userName,userName]; arguments []; default message [userName]]; default message [用户名不能为空]] ]

但是在日常工作中,无论服务器异常还是成功都会向前端返回http 200,还有固定的json数据结构,然后前端从返回数据中根据状态判断业务是否成功。这个时候就可以使用全局异常处理对异常信息进行拦截,然后将错误信息封装成正确的返回格式。可以参考作者之前发的文章。

 手把手带你实现JAVA自定义异常和全局异常处理

在全局异常处理器中添加如下代码

@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
public Response handleBizException(MethodArgumentNotValidException e) {log.error("BusinessException,code={},value={}", e.getParameter(), e.getMessage());BindingResult bindingResult = e.getBindingResult();List fieldErrors = bindingResult.getFieldErrors();// 对未通过校验的字段进行错误信息拼接返回StringBuilder stringBuilder = new StringBuilder();for (FieldError fieldError : fieldErrors) {stringBuilder.append(fieldError.getField()).append("-").append(fieldError.getDefaultMessage());}return SingleResponse.buildFailure(String.valueOf(500), stringBuilder.toString());
}

添加全局异常处理之后的效果:

使用GET进行参数校验,注意使用GET请求对参数进行校验需要在Controller上加 @Validated

//请求参数
@GetMapping("/user/userinfo")
public SingleResponse getUserInfo(@NotNull(message = "用户ID不能为空") @Min(value = 1,message = "用户ID不能小于1") Integer userId){System.out.println("进入获取用户信息方法-------------");// 校验通过走服务层逻辑//返回结果return SingleResponse.buildSuccess();
}
//路径参数
@GetMapping("/user/userinfo/{userId}")
public SingleResponse getUserInfo2(@PathVariable("userId")@NotNull(message = "用户ID不能为空") @Min(value = 1,message = "用户ID不能小于1") Integer userId){System.out.println("进入获取用户信息方法-------------");// 校验通过走服务层逻辑//返回结果return SingleResponse.buildSuccess();
}

到此Spring validation参数校验的简单使用和结合全局异常处理返回错误信息就到此结束了,感兴趣的小伙伴赶紧去试试吧。

相关内容

热门资讯

年内两度减持 獐子岛再遭第三大... 来源:深圳商报 12月29日晚间,獐子岛(002069.SZ)公告称,股东北京吉融元通资产管理有限...
闻泰科技起诉荷兰索赔80亿美元... 关于安世半导体被荷兰干预事件,闻泰科技董事长杨沐称,公司已于今年10月15日提交争端通知,若问题在6...
政策突变,黄金白银大跌!极速跳... 暴涨之后短线极速下跌,金属牛还在否? 12月29日,多个强势的金属品种尾盘跳水,其中钯、铂更是跌停,...
这个重要法律十年了 2015年12月27日,《中华人民共和国反恐怖主义法》(以下简称反恐怖主义法)经全国人大常委会审议通...
上海银行股份有限公司关于诉讼事... 上海银行股份有限公司(以下简称“公司”)董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述...
制度托底生育友好 江苏率先实现... 原题:制度托底 生育友好 江苏生娃基本不花钱 近年来,江苏加快建立全周期的生育保障体系,助力“怀得上...
古巴外长:美国正在加大对古“经... 新华社哈瓦那12月29日电(记者蒋彪)古巴外交部长罗德里格斯29日表示,美国正在加强对古巴的“极限施...
离职3个月起诉“老东家” 【深圳商报讯】(记者 詹钰叶)根据上海市高级人民法院官网近期披露的信息,外资公募联博基金前副总经理朱...
制度黑幕屡被诟病,韩国政府计划... 【环球时报驻韩国特约记者 黎枳银】综合韩联社、《朝鲜日报》等韩媒报道,韩国政府正式决定分阶段全面叫停...