Advise Controller-Methode * vor * @Valid Annotation wird behandelt

Ich füge einem erholsamen Webservice mit Spring MVC 4.1 eine Geschwindigkeitsbegrenzung hinzu.

Ich habe ein @ erstel@RateLimited Anmerkung, die ich auf Controller-Methoden anwenden kann. Ein Spring-AOP-Aspekt fängt Aufrufe dieser Methoden ab und löst eine Ausnahme aus, wenn zu viele Anforderungen vorliegen:

@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RateLimitingAspect {

    @Autowired
    private RateLimitService rateLimitService;

    @Before("execution(* com.example..*.*(.., javax.servlet.ServletRequest+, ..)) " +
            "&& @annotation(com.example.RateLimited)")
    public void wait(JoinPoint jp) throws Throwable {

        ServletRequest request =
            Arrays
                .stream(jp.getArgs())
                .filter(Objects::nonNull)
                .filter(arg -> ServletRequest.class.isAssignableFrom(arg.getClass()))
                .map(ServletRequest.class::cast)
                .findFirst()
                .get();
        String ip = request.getRemoteAddr();
        int secondsToWait = rateLimitService.secondsUntilNextAllowedAttempt(ip);
        if (secondsToWait > 0) {
          throw new TooManyRequestsException(secondsToWait);
        }
    }

Dies alles funktioniert einwandfrei, außer wenn das@RateLimitedei der @ controller-Methode sind die Parameter mit @ markier@Valid, z.B.

@RateLimited
@RequestMapping(method = RequestMethod.POST)
public HttpEntity<?> createAccount(
                           HttpServletRequest request,
                           @Valid @RequestBody CreateAccountRequestDto dto) {

...
}

Das Problem: Wenn die Validierung fehlschlägt, wirft der ValidatorMethodArgumentNotValidException, das von einem @ behandelt wi@ExceptionHandler, das eine Fehlerantwort an den Client zurückgibt und niemals mein @ auslö@Before und damit die Geschwindigkeitsbegrenzung umgehen.

Wie kann ich eine solche Webanforderung so abfangen, dass sie Vorrang vor der Parameterüberprüfung hat?

Ich habe überlegt, Spring Interceptors oder einfache Servlet-Filter zu verwenden, aber sie werden durch einfache URL-Muster abgebildet, und ich muss nach GET / POST / PUT / usw. differenzieren.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage