记录背景:
接口参数空校验
常规校验:
public class User{
@NotEmpty(message = "名字不能为空")
private String name;
}
//在controller中使用此校验
@PostMapping("/add")
public void add(@RequestBody @Valid User user) {
......
}
//如果参数不符合Model中定义的话,程序中就回抛出异常,并提示错误信息。
说明:
由于项目复杂,常规校验不适用,故记录low校验写法。
//jar包
<!-- oval 参数校验 -->
<dependency>
<groupId>net.sf.oval</groupId>
<artifactId>oval</artifactId>
<version>1.86</version>
</dependency>
//校验工具类
public class ValidatorUtils {
/**
* 描述:校验请求参数
*/
public static Result validatorRequestParam(Object obj) {
Validator validator = new Validator();
List<ConstraintViolation> ret = validator.validate(obj);
if (ret.size() > 0) {
//校验失败
return Result.failed(ret.get(0).getMessageTemplate());
}
return Result.succeed(null);
}
}
import net.sf.oval.constraint.NotBlank;
import net.sf.oval.constraint.NotNull;
//请求dto类
public class User{
@NotEmpty(message = "名字不能为空")
private String name;
}
//在controller中使用此校验
@PostMapping("/add")
public Result add(@RequestBody User user) {
Result result = ValidatorUtils.validatorRequestParam(user);
if (!result.successful()) {
//校验未通过,直接返回
return result;
}
//校验通过,执行后续业务
......
}
//统一返回格式
public class Result<T> implements Serializable {
private T data;
private Integer resp_code;
private String resp_msg;
public boolean successful() {
return resp_code == CodeEnum.SUCCESS.getCode().intValue();
}
}
改善版本: 使用aop统一校验,无需在每个接口写重复校验代码
//增加aop配置文件
import cloud.utils.ValidatorUtils;
import cn.hutool.http.Method;
import com.alibaba.fastjson.JSON;
import com.open.capacity.common.web.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @author 校验请求参数aop
*/
@Slf4j
@Aspect
@Configuration
public class ValidatorRequestParamAspect {
/**
* 定义切点,controller包路径
*/
@Pointcut("execution(* cloud.api.controller..*.*(..))")
public void pointcut() {
}
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint pjp) {
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//请求参数
String params = "";
if (pjp.getArgs().length > 0) {
if ("POST".equals(request.getMethod())) {
Object object = pjp.getArgs()[0];
params = JSON.toJSONString(object);
Result result = ValidatorUtils.validatorRequestParam(object);
if (!result.successful()) {
log.info("\r\n请求数据>>请求地址:{} 请求参数:{} \r\n请求返回:{}",
request.getRequestURL().toString(), params, JSON.toJSONString(result));
return result;
}
} else if ("GET".equals(request.getMethod())) {
params = request.getQueryString();
}
}
// result的值就是被拦截方法的返回值,proceed()继续调用真正需要调用的方法
Object result = pjp.proceed();
log.info("\r\n请求数据>>请求地址:{} 请求参数:{} \r\n请求返回:{}",
request.getRequestURL().toString(), params, JSON.toJSONString(result));
return result;
} catch (Throwable e) {
log.error("校验请求参数aop错误", e);
return Result.failed("服务网络出错,请稍后再试");
}
}
}
增加aop配置文件后,controller直接写业务代码即可,无需再次校验
@PostMapping("/add")
public Result add(@RequestBody User user) {
......
}
注意点:
需要导入
import net.sf.oval.constraint.NotBlank;
import net.sf.oval.constraint.NotNull;
不要导入 其它jar包下的NotNull、NotBlank
oval参数校验常用注解:
null校验
@NotNull
字符串类型使用
@Email 检查字符串是否为有效的电子邮件地址
@Length 检查字符串长度。 参数: max,min
示例
@Length(max=10,min=5,message=“长度位于5到10之间”)
@MaxLength 字符串最大长度限制
@MinLength 字符串最小长度限制
@NotBlank 检查字符串是否为空,字符串" "认为为空。
@NotEmpty 检查字符串不为"",字符串" "认为不为空。
数值类型使用
@Range 检查数字是否在给定范围内,和Double进行比较。参数: max,min
示例
@Range (max=10,min=5,message=“数字大小位于5到10之间”)
@Max 数字最大限制
@Min 数字最小限制
@NotNegative 检查数字是否大于或等于零。非负数。
集合数组
@Size 检查集合数组的大小。参数: max,min
@MaxSize 集合数组最大长度限制
@MinSize 集合数组最小长度限制