在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中是如果字段为空返回的提示内容
@Data
public 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;
/**
* @author
* @title 响应实体类
* @param <T>
*/
@Data
public class Result<T> {
private String code;//返回码
private String msg;//消息
private T data;//返回数据
/**
* @title 成功消息
* @param
* @return
*/
public static <T> Result<T> OK() {
return rspMsg(ResponseEnum.SUCCESS);
}
/**
* @title 失败消息
* @param
* @return
*/
public static <T> Result<T> error() {
return rspMsg(ResponseEnum.SERVER_INNER_ERR);
}
/**
* @title 失败消息
* @param
* @return
*/
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;
}
/**
* @title 自定义消息
* @param
* @return
*/
public static <T> Result<T> rspMsg(ResponseEnum responseEnum) {
Result<T> message = new Result<T>();
message.setCode(responseEnum.getCode());
message.setMsg(responseEnum.getMsg());
return message;
}
/**
* @title 返回数据
* @param data
* @return
*/
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;
}
/**
* @title 返回数据
* @param data
* @return
*/
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;
}
/**
* @title 返回数据-自定义code
* @param data
* @return
*/
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;
}
/**
* @author
* @title 响应消息枚举
*/
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;
@ControllerAdvice
public 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 才有效,如下文章来源:https://www.toymoban.com/news/detail-719838.html
@PostMapping("/test")
public Result test(@RequestBody @Valid aaa dto) {
//接口其他逻辑操作
return Result.ok("非空参数都有值");
}
结束:上面是文章全部内容,如果接口数量少,直接前六步就行,接口过多,可以使用拦截器,如有问题和建议欢迎留言评论。文章来源地址https://www.toymoban.com/news/detail-719838.html
到了这里,关于java如何优雅的实现参数非空校验,快速实现参数非空校验,使用@valid实现参数非空校验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!