发现一个参数校验的框架:
vennarshulytz/validation-parent: Custom validation starter for Spring Boot
pom.xml引入依赖:
<dependency>
<groupId>io.github.vennarshulytz</groupId>
<artifactId>validation-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
springboot启动类加注解:
@EnableValidation
controller类加注解:
@ValidatedExt
模拟使用:
@RequestMapping("/getDetail")
public R<GetDetailRes> getDetail(@RequestBody @ValidationRules({
// @ValidationRule(type = GetDetailReq.class, validators = {
// @ValidateWith(validator = IdIsNotNullValidator.class, fields = @FieldConfig(names = {"id", "id2"}, message = "ID不能为空")),
// }),
@ValidationRule(custom = TestCustomValidator.class)
}) GetDetailReq req
// , @RequestParam @IdIsNotNullCheck(message = "学员ID不能为空") BigDecimal userId
) {
return R.SUCCESS();
}
校验单个参数:
import cn.hutool.core.util.StrUtil;
import io.github.vennarshulytz.validation.validator.FieldValidator;
import io.github.vennarshulytz.validation.validator.builtin.AbstractDecimalValidator;
import java.lang.annotation.Annotation;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class IdIsNotNullValidator extends AbstractDecimalValidator implements FieldValidator {
@Override
public String validate(String fieldName, Object value, Map<String, Object> params, boolean enableI18n) {
return isValid(value) ? null : this.getErrorMessage(params);
}
@Override
public Map<String, Object> parseParams(Annotation annotation) {
if (annotation instanceof IdIsNotNullCheck) {
IdIsNotNullCheck idIsNotNullCheck = (IdIsNotNullCheck) annotation;
Map<String, Object> params = new HashMap<>();
params.put("message", idIsNotNullCheck.message());
return params;
} else {
return Collections.emptyMap();
}
}
private String getErrorMessage(Map<String, Object> params) {
String errorMessage = (String) params.get("message");
if (StrUtil.isNotBlank(errorMessage)) {
return errorMessage;
} else {
return this.getDefaultMessage();
}
}
private boolean isValid(Object value) {
BigDecimal id = this.toBigDecimal(value);
return id != null && id.compareTo(BigDecimal.ZERO) > 0 && id.scale() == 0;
}
}
行内参数校验:
import io.github.vennarshulytz.validation.annotation.ValidateWith;
import java.lang.annotation.*;
@Documented
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@ValidateWith(validator = IdIsNotNullValidator.class)
public @interface IdIsNotNullCheck {
String message();
}
多个参数组合校验(或查库等复杂操作):
import io.github.vennarshulytz.validation.validator.CustomValidator;
import io.github.vennarshulytz.validation.validator.ValidationResult;
public class TestCustomValidator implements CustomValidator<GetDetailReq> {
@Override
public void validate(GetDetailReq request, ValidationResult result) {
if(DataUtil.idIsNull(request.getId()) && DataUtil.idIsNull(request.getId2())) {
result.addError("id,id2", "id或id2不能为空", null);
}
}
}
统一处理校验失败的返回格式:
import io.github.vennarshulytz.validation.exception.ValidationException;
import io.github.vennarshulytz.validation.validator.ValidationResult;
import org.springframework.core.annotation.Order;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.stream.Collectors;
@Order(-1) // 优先级最高
@RestControllerAdvice
public class ValidationExceptionHandler {
@ExceptionHandler(ValidationException.class) // 只处理ValidationException异常
public Object handleValidationException(ValidationException e) {
String errors = e.getErrors().stream().map(ValidationResult.FieldError::getMessage).distinct().collect(Collectors.joining("; "));
return R.ERROR(errors);
}
}