在java项目接口中,有些必传参数需要进行非空校验,如果参数过多,代码会繁杂且冗余,如何优雅的对参数进行非空校验,下面是实现流程
目录
一、整体思路
用实体类接收参数,使用非空注解编辑参数内容
使用 @Valid 注解对参数进行拦截,整体进行非空校验
二、引入依赖
1、SpringBoot项目
如果是SpringBoot项目,引入web开发包,就不需要再单独引入@valid依赖了、因为他存在于Web开发包中的最核心之中
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.5.RELEASE</version></dependency>
2、其他框架项目
如果不是SpringBoot项目,要在Maven的Pom中显式引入@valid依赖
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version></dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version></dependency>
三、编辑入参实体类
将接口入参使用实体类接收,在实体类中定义参数字段,并使用对应的注解进行注释
- String类型使用@NotBlank
- List类型使用@NotEmpty
- 其他类型使用@NotNull
- message中是如果字段为空返回的提示内容
@Datapublic class aaa { @NotBlank(message = "testStr不能为空") private String testStr; @NotNull(message = "testInt不能为空") private Integer testInt; @NotEmpty(message = "testList不能为空") private List<Long> testList;}
四、定义返回的实体类
package com.test;import lombok.Data;@Datapublic class Result<T> { private String code;//返回码 private String msg;//消息 private T data;//返回数据 public static <T> Result<T> OK() { return rspMsg(ResponseEnum.SUCCESS); } public static <T> Result<T> error() { return rspMsg(ResponseEnum.SERVER_INNER_ERR); } public static <T> Result<T> error(String msg) { Result<T> message = new Result<T>(); message.setCode(ResponseEnum.FAIL.code); message.setMsg(msg); return message; } public static <T> Result<T> waring(String msg) { Result<T> message = new Result<T>(); message.setCode("2"); message.setMsg(msg); return message; } public static <T> Result<T> rspMsg(ResponseEnum responseEnum) { Result<T> message = new Result<T>(); message.setCode(responseEnum.getCode()); message.setMsg(responseEnum.getMsg()); return message; } public static <T> Result<T> OK(T data) { Result<T> responseData = new Result<T>(); responseData.setCode(ResponseEnum.SUCCESS.getCode()); responseData.setData(data); responseData.setMsg(ResponseEnum.SUCCESS.getMsg()); return responseData; } public static <T> Result<T> ok(T data) { Result<T> responseData = new Result<T>(); responseData.setCode(ResponseEnum.SUCCESS.getCode()); responseData.setData(data); responseData.setMsg(ResponseEnum.SUCCESS.getMsg()); return responseData; } public static <T> Result<T> OK(String code , T data) { Result<T> responseData = new Result<T>(); responseData.setCode(code); responseData.setData(data); return responseData; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; } public enum ResponseEnum { // 可以根据自己的实际需要增加状态码 SUCCESS("0", "操作成功"), FAIL("1", "操作失败"), SERVER_INNER_ERR("500","未知异常,请联系管理管"), PARAM_LACK("100" , "非法参数"), ; private String code; private String msg; ResponseEnum(String code, String msg) { this.code = code; this.msg = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }}
五、Controller层参数校验
在Controller层加上 @RequestBody 和 @Valid 注解,并且加上 BindingResult res 对参数进行捕获
@PostMapping("/test")public Result test(@RequestBody @Valid aaa dto, BindingResult res) { if (res != null) { //获取校验内容是否为空 if (res.hasErrors()) { List<ObjectError> errorList = res.getAllErrors(); List<String> resultList = new ArrayList<>(); for (ObjectError error : errorList) { //获取所有校验错误信息 resultList.add(error.getDefaultMessage()); } //将错误信息返回 return Result.error(String.join(",", resultList)); } } //接口其他逻辑操作 return Result.ok("非空参数都有值");}
六,测验结果
如果调用此接口,全部参数都为空,则会返回下面内容
{ "msg": "testStr不能为空,testInt不能为空,testList不能为空", "code": 1}
七、拦截器补充
其实到上面第六步就已经完成了,但是如果接口过多,每个接口里面都要写这一长串拦截的内容,代码过于冗余,于是加上了一个拦截器
1、加拦截器内容
整个项目加上一个拦截器,拦截器内容如下
package com.test.interceptor;import com.test.common.Result;import org.springframework.validation.BindingResult;import org.springframework.validation.ObjectError;import org.springframework.web.bind.MethodArgumentNotValidException;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import java.util.ArrayList;import java.util.List;@ControllerAdvicepublic class ControllerExceptInterceptor { @ResponseBody @ExceptionHandler(MethodArgumentNotValidException.class) public Result handleValidException(MethodArgumentNotValidException e) { //日志记录错误信息 // log.error(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage()); BindingResult bindingResult= e.getBindingResult(); if (bindingResult != null) { if (bindingResult.hasErrors()) { List<ObjectError> errorList = bindingResult.getAllErrors(); List<String> resultList = new ArrayList<>(); for (ObjectError error : errorList) { resultList.add(error.getDefaultMessage()); } return Result.error(String.join(",", resultList)); } } return Result.error(); }}
2、修改Controller层内容
去掉controller层中的 BindingResult res 内容,去掉参数非空校验代码,但是必须要加 @RequestBody @Valid 才有效,如下
@PostMapping("/test")public Result test(@RequestBody @Valid aaa dto) { //接口其他逻辑操作 return Result.ok("非空参数都有值");}
结束:上面是文章全部内容,如果接口数量少,直接前六步就行,接口过多,可以使用拦截器,如有问题和建议欢迎留言评论。
来源地址:https://blog.csdn.net/qq_41444892/article/details/131912144