How do I get my Spring aspects to execute before @Valid/@Validated annotation on a spring controller method?
Asked Answered
C

1

6

I have this service/controller method:

public ResponseEntity<PolicyDTO> addPolicy(@Valid @RequestBody PolicyDTO policy)
        throws InternalServerException, BadRequestException {
    log.debug("Adding a new policy");
}

Notice the @Valid annotation in the method params

For this controller we have defined the following aspect class:

@Aspect
@Component
public class BackwardsCompatibilityHandler {
@Around("execution(* com.company.PolicyController.addPolicy(..))")
public Object ControllerMethod(JoinPoint jp) 
{
    // DO Code before and after the method call
}

The main reason behind this aspect / proxy is to intercept method calls and do some pre / post processing over the input params / returned results.

The main problem that we face now is that the @Valid annotation is handled before the aspect before and after code is actually executed.

Any idea on how we can make the Validation check run inside our AOP code? I know there is a way to do this by manually calling the validator inside the method, but would like not to touch the existing code that much... so any ideas other than this, if there are...

Right now the order of execution is this:

  1. Validation check - triggered by the @Valid anotation
  2. Own code - aspect - before method call
  3. Actual method call
  4. Own code - aspect - after method call

And we would like to have something more like (first our code and then the Valid annotation):

  1. Own code - aspect - before method call
  2. Validation check - triggered by the @Valid anotation
  3. Actual method call
  4. Own code - aspect - after method call

Please skip over compiler errors or such, this code is only for demonstration purposes, it's not the real code :)

Cyaneous answered 1/9, 2016 at 11:59 Comment(11)
You cannot... As the method is invoked after validation, this is hardcoded into the RequestMappingHandlerAdapter. imho you really should be using a HandlerInterceptor and operate on the request.Zenas
This will help you #28975525Monteverdi
Right now I am using AspectJ to intercept the method calls and manipulate the input / output objects in a nice Java / Modern / DTOfashion :) Going back to modifying the request / the response would be something at least not desirable :)Cyaneous
You could use full AspectJ via LTW instead of proxy-based Spring AOP and utilise the power of other pointcut types such as call() instead of execution(). A call() pointcut is fired before its the corresponding execution() pointcut because it weaves the caller, not the callee.Primate
@M.Deinum You should post your comment as an answer to make this question complete.Impermeable
@Primate You should post your comment as an answer to make this question complete.Impermeable
I guess @Cyaneous should first indicate whether any of the comments helped him at all. I am not sure my little comment qualifies as an answer.Primate
Thank you all for your suggestions. Unfortunately we could not solve this issue and we had to double back and redo our code so that we don't end up in this situation in the first place. Thank you all.Cyaneous
With full AspectJ you could surely have solved the problem, but probably you had reasons why you did not tread that path. And refactoring code so as to avoid issues needing workarounds in the first place has my full sympathy. AOP should not be used to patch up bad application design. ;-)Primate
100% agree. Thank you :)Cyaneous
Sorry to rebump this, So it is actually not possible right?Beguin
N
0

Add the following controller advice in your application.

@ControllerAdvice
public class ApplicationControllerAdvice {

@InitBinder
@<YourCustomAnnotation>
protected void activateBeanPropertyAccess(DataBinder dataBinder) {
    dataBinder.initBeanPropertyAccess();
}
}

The @YourCustomAnnotation should call the class BackwardsCompatibilityHandler. So, after this all the constraints validator will be called.

Nicosia answered 24/5, 2022 at 9:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.