Spring 验证RequestBody和Param中的所有字符串字段

Spring 验证RequestBody和Param中的所有字符串字段,spring,spring-boot,spring-mvc,spring-bean,spring-validator,Spring,Spring Boot,Spring Mvc,Spring Bean,Spring Validator,我正在使用基于SpringBoot的rest服务,并希望对所有字符串应用默认验证 我想对@RequestBody或的任何字符串字段应用默认验证 @帕拉姆。注意:我需要一个默认验证,也就是说,我希望能够在不注释所有字符串字段的情况下进行验证 我希望能够对字段进行注释以跳过验证 我计划使用控制器建议来实现这一点,以便所有控制器都得到验证 我已经研究过如何使用属性源编辑器,但这看起来不像是为了抛出验证错误而设计的。我也不确定是否可以访问该字段上的应用注释 使用自定义spring验证器实现,我不确定

我正在使用基于SpringBoot的rest服务,并希望对所有字符串应用默认验证

  • 我想对@RequestBody或的任何字符串字段应用默认验证 @帕拉姆。注意:我需要一个默认验证,也就是说,我希望能够在不注释所有字符串字段的情况下进行验证
  • 我希望能够对字段进行注释以跳过验证
  • 我计划使用控制器建议来实现这一点,以便所有控制器都得到验证
我已经研究过如何使用属性源编辑器,但这看起来不像是为了抛出验证错误而设计的。我也不确定是否可以访问该字段上的应用注释

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


我很确定我不是唯一一个在寻找类似问题答案的人。是否有建议?

您可以将@Valid与@RequestBody结合使用,以检查使用javax.validation.constraints注释(@NotBlank、@NotNull等)注释的所有字段

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

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

编辑:在澄清之后

不确定定制Spring验证器,但使用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());
                }

            }
        }
    }

}
}
@组件
@面貌
公共类控制器建议{
专用静态最终记录器=
LoggerFactory.getLogger(ControllerAdvice.class);
@切入点(“在(@org.springframework.web.bind.annotation.RestController*)内)
公共空间控制器(){
}
@在(“controller()”)之前
重新启动前的公共无效PI(JoinPoint jp){
对象[]args=jp.getArgs();
MethodSignature=(MethodSignature)jp.getSignature();
Annotation[][]annotations=signature.getMethod().getParameterAnnotations();
对于(int i=0;i0
&&注释[i][0].annotationType().equals(RequestParam.class)){
字符串s=(字符串)args[i];
logger.info(“验证请求参数”+s);
}
//验证@RequestBody的字符串字段
如果(注释[i]。长度>0
&&注释[i][0].annotationType().equals(RequestBody.class)){
字段[]allFields=args[i].getClass().getDeclaredFields();
用于(字段f:所有字段){
//跳过带有特定注释的字段
如果(f.isAnnotationPresent(SkipValidation.class)){
继续;
}
if(f.getType().equals(String.class)){
info(“验证字符串字段:+f.getName());
}
}
}
}
}
}

以备将来有人需要

我发现Spring有一个专门针对请求主体的通知
RequestBodyAdvice

我扩展了Spring的
RequestBodyAdviceAdapter
,它实现了
RequestBodyAdvice
,并在bodyread之前和之后提供了
抽象方法


我进一步澄清了我的问题。我知道如何使用注释。需要一种在所有字符串字段上应用默认验证器的方法,而不需要在整个代码库中对它们进行注释。感谢您提供了很好的示例代码。像这样的东西也会起作用。我最终使用了Spring的
RequestBodyAdviceAdapter
,因为它更方便。向上投票。