aconseje el método del controlador * antes * @ Se maneja la anotación válida

Estoy agregando limitación de velocidad a un servicio web tranquilo usando Spring MVC 4.1.

Creé un@RateLimited Anotación que puedo aplicar a los métodos de controlador. Un aspecto Spring AOP intercepta las llamadas a estos métodos y lanza una excepción si ha habido demasiadas solicitudes:

@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);
        }
    }

Todo esto funciona perfectamente, excepto cuando el@RateLimited El método del controlador tiene parámetros marcados como@Valid, p.ej.:

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

...
}

El problema: si la validación falla, el validador arrojaMethodArgumentNotValidException, que es manejado por un@ExceptionHandler, que devuelve una respuesta de error al cliente, sin activar nunca mi@Before y por lo tanto eludiendo la limitación de velocidad.

¿Cómo puedo interceptar una solicitud web como esta de una manera que tenga prioridad sobre la validación de parámetros?

He pensado en usar Spring Interceptors o filtros de servlet simples, pero están mapeados por patrones de URL simples y necesito diferenciar por GET / POST / PUT / etc.

Respuestas a la pregunta(2)

Su respuesta a la pregunta