首页 > 解决方案 > 验证 RequestBody 和 Param 中的所有字符串字段

问题描述

我正在使用基于 spring-boot 的休息服务,并希望对所有字符串应用默认验证。

我已经研究过使用属性源编辑器,但这看起来并不是为了从那里抛出验证错误。我也不确定我是否可以访问该字段上应用的注释。

使用自定义弹簧验证器实现,我不确定如何处理复杂对象中的嵌套字段。

我很确定我不是唯一一个为此类问题寻找答案的人。有推荐吗?

标签: springspring-bootspring-mvcspring-beanspring-validator

解决方案


您可以将@Valid 与@RequestBody 结合使用来检查所有使用javax.validation.constraints注释(@NotBlank、@NotNull 等)注释的字段。更多信息在这里

对于@RequestParam 和@PathVariable,这里有类似的方法

我的建议是在寻求控制器建议之前使用这种方法。

编辑:在你澄清之后。

不确定自定义 Spring Validator 但可以使用 AOP 和反射。我在下面实现了一个示例,希望对您有所帮助。

@Component
@Aspect
public class ControllerAdvice {

private static final Logger logger = 
LoggerFactory.getLogger(ControllerAdvice.class);

@Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
public void controller() {
}

@Before("controller()")
public void beforeRestAPI(JoinPoint jp) {
    Object[] args = jp.getArgs();
    MethodSignature signature = (MethodSignature) jp.getSignature();
    Annotation[][] annotations = signature.getMethod().getParameterAnnotations();
    for (int i = 0; i < args.length; i++) {
        // validate @RequestParam arguments
        if (args[i] instanceof String && annotations[i].length > 0
                && annotations[i][0].annotationType().equals(RequestParam.class)) {
            String s = (String) args[i];
            logger.info("validating RequestParam " + s);
        }
        // validate String fields of @RequestBody
        if (annotations[i].length > 0 
                && annotations[i][0].annotationType().equals(RequestBody.class)) {
            Field[] allFields = args[i].getClass().getDeclaredFields();
            for (Field f : allFields) {
                // skip fields with specific annotation 
                if(f.isAnnotationPresent(SkipValidation.class)) {
                    continue;
                }
                if (f.getType().equals(String.class)) {
                    logger.info("validating string field: " + f.getName());
                }

            }
        }
    }

}
}

推荐阅读