@RequestMapping(
value = "test",
method = RequestMethod.POST)
public FrogTest test(@RequestBody FrogTest bean) {
if (bean.getName() == null) {
throw new MyException("A02", "名称不能为空");
}
if (bean.getSize() > 100) {
throw new MyException("A03", "size值超过允许最大值");
}
return bean;
}
通常通过以上方式,对前端请求参数进行校验,如果请求bean(FrogTest)中需要校验的属性太多时,对每个参数写一个对应的if判断,代码可读性很差,所以可以在请求对象属性加上注解来校验其合法性。
public class FrogTest implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@NotEmpty(message = "名称项不能为空")
private String name;
private String describ;
private LocalDateTime date;
@NotEmpty(message = "状态标识项不能为空")
@Pattern(regexp = "[012]", message = "无效的状态标志")
private String state;
@SizeValidator(maxSize = 100.1, message = "值太大")
private Double size;
...
省略getter和setter
}
其中@NotEmpty和@Pattern是javax.validation.constraints包中注解,前者表示不为空,后者表示为特定格式,现在表示只能为0、1、2。@SizeValidator是自定义注解,用来校验值得大小(可以用@Size),如下:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {SizeValidatorImpl.class}
)
public @interface SizeValidator {
double maxSize() default 10000.0;
String message() default "值得大小不合法";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
约束实现类:
public class SizeValidatorImpl implements ConstraintValidator<SizeValidator, Double> {
private double maxSize;
@Override
public void initialize(SizeValidator constraintAnnotation) {
maxSize = constraintAnnotation.maxSize();
}
@Override
public boolean isValid(Double value, ConstraintValidatorContext context) {
if (value > 0 && value < maxSize) {
return true;
}
return false;
}
}
请求参数增加@Valid注解
@RequestMapping(
value = "test",
method = RequestMethod.POST)
public FrogTest test(@RequestBody @Valid FrogTest bean) {
/*不需要通过if判断校验
if (bean.getName() == null) {
throw new MyException("A02", "名称不能为空");
}
if (bean.getSize() > 100) {
throw new MyException("A03", "size值超过允许最大值");
}*/
return bean;
}
在SpringBoot项目通用返回值与全局异常处理的基础上修改
@RestControllerAdvice
public class MyExceptionHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@ExceptionHandler(Exception.class)
public Object handleException(Exception e, HttpServletRequest request, HttpServletResponse response){
logger.error("请求:{}发生异常:{}", request.getRequestURI(), e);
Result result = new Result();
result.setSuccess(false);
if (e instanceof MyException) {
result.setErrorCode(((MyException) e).getErrorCode());
result.setErrorMsg(((MyException) e).getErrorMsg());
} else {
result.setErrorCode(MyExceptionEnum.SYSTEM_ERROR.getCode());
result.setErrorMsg(MyExceptionEnum.SYSTEM_ERROR.getMsg());
}
return result;
}
/**
* 自定义注解异常拦截
*/
@ExceptionHandler({BindException.class, ConstraintViolationException.class, MethodArgumentNotValidException.class})
public Object handleMethodArgumentNotValidException(Exception e, HttpServletRequest request) {
logger.error("请求:{}发生异常:{}", request.getRequestURI(), e);
// 错误信息
StringBuilder sb = new StringBuilder("参数校验失败:");
// 错误信息map
Map<String, String> error = new HashMap<>();
String msg = "";
if (!(e instanceof BindException) && !(e instanceof MethodArgumentNotValidException)) {
for (ConstraintViolation cv: ((ConstraintViolationException)e).getConstraintViolations()) {
msg = cv.getMessage();
sb.append(msg).append(";");
Iterator<Path.Node> it = cv.getPropertyPath().iterator();
Path.Node last = null;
while (it.hasNext()) {
last = (Path.Node)it.next();
}
/*for(last = null; it.hasNext(); last = (Path.Node)it.next()) {
}*/
error.put(last != null ? last.getName() : "", msg);
}
} else {
List<ObjectError> allErrors = null;
if (e instanceof BindException) {
allErrors = ((BindException)e).getAllErrors();
} else {
allErrors = ((MethodArgumentNotValidException)e).getBindingResult().getAllErrors();
}
// 拼接错误信息
for (ObjectError oe : allErrors) {
msg = oe.getDefaultMessage();
sb.append(msg).append(";");
if (oe instanceof FieldError) {
error.put(((FieldError)oe).getField(), msg);
} else {
error.put(oe.getObjectName(), msg);
}
}
}
Result<Map> result = new Result<>(error);
result.setSuccess(false);
result.setErrorCode(MyExceptionEnum.REQUESTPARAM_ERROR.getCode());
result.setErrorMsg(MyExceptionEnum.REQUESTPARAM_ERROR.getMsg() + sb.toString());
return result;
}
}