0

I have a function under class MyController:

@RestController
@RequestMapping(value = "/api/service")
public class MyController {

   @PostMapping(value = "add_person")
   public MyResponse addPerson(@RequestBody Person person) {
       // ...
   }

   @PostMapping(value = "add_person_2")
   public MyResponse addPerson(@PathVariable(value = "person_age") Int age, @RequestBody Person person) {
       // ...
   }
}

I have setup AspectJ in my project to have a AOP logic to run whenever those two addPerson(...) method above is called:

@Around("execution(public MyResponse addPerson(..))")
public void around(ProceedingJoinPoint joinPoint) {
   // NO matter which addPerson(...) is executing, I am only interested in the
   // parameter value annotated with @RequestBody.
   // How can I access the parameter that passed in addPerson(...) & is annotated with
   // @RequestBody through ProceedingJoinPoint ?
}

My question is mentioned in above code comment. I wonder how can I access the parameter annotated with @RequestBody in my AOP function? I don't want to check parameter type or name, but interested to know how to access parameter by checking the annotation through ProceedingJoinPoint. Is it possible?

kriegaex
  • 63,017
  • 15
  • 111
  • 202
Leem
  • 17,220
  • 36
  • 109
  • 159
  • Is the request body parameter reliable the last (or only) parameter in the method signature like in your example or could it be at any position? What about its type? You said you do not want to check it, but can we assume it is always a `Person` or not? The answers to these two questions determine the solution and whether it is elegant or more complicated. As your method parameters only consist of comments, I have no idea what you want to do with the request body once you got it. So please show what the rest of your around advice would look like after you got the request body. – kriegaex Aug 07 '19 at 23:44
  • The requestBody parameter could be in any position. It would be nice if the answer including when it is always `Person` type and when it is not. – Leem Aug 08 '19 at 04:38

1 Answers1

1

I do not want to mark this question as a duplicate because it is no exact duplicate, but my answer here should answer the question about how to

  • match an annotated parameter at any position,
  • get the annotation + the parameter value itself.

The linked answer uses a @Before advice. If you want to somehow replace the value by another one in an @Around advice when calling proceed() this is also possible, but was not asked here and my request for seeing more of the advice method body was also ignored.

If you want to limit to annotated Person parameters, you would have to use the fully qualified class name my.package.Person instead of the * inside (*) and do the corresponding cast after accessing the parameter in the advice body.

In my comment I also asked if the parameter has a fixed relative position in the parameter list such as first, last or second/third from left/right. If the OP would have confirmed such a fixed relative position, reflection would not be necessary and the corresponding parameter could be bound to an advice method parameter directly via args() pointcut designator. This would be quite elegant and eliminate the need to loop over getArgs() or over a two-dimensional array of parameter annotations.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • How about some feedback? You have not accepted my answer yet, so is there anything missing? Do you need more information? If so, about what? – kriegaex Aug 15 '19 at 01:31