Reputation: 121
recently I was searching for how to change the headers and body of the HttpServletRequest
object before starting the controller logic, the only way that I found of achieve this is with an aspect, all good with this solution but the problem is that I have a lot of controllers classes, I need to change the value of an specific header in these controllers, I have added all my classes in my aspect:
@Pointcut("execution(* com.mypackage.Controller1..*(..)) || " +
"execution(* com.mypackage.Controller3.someMethod*(..))
//A lot of methods and packages
private void anyMethodWithHeader(){
@Around("anyMethodWithHeader()")
public ResponseEntity<Map<String, Object>> changeHeaderValue(ProceedingJoinPoint jp) throws Throwable{
//Here I got the object array with the arguments that I need
So my question is:
There is a way in the @PointCut
to put a regex or conditional or something like that in just one line or two, to get a specific header?
I mean, I have a lot of controllers, and those controllers receive a lot of headers, but I just want to change the value of a header named test-token
, all I want is to avoid the addition of one more line in my aspect every time that I add a new controller in my project.
I was trying adding the package of the @RequestHeader
in my aspect and other things but nothing works.
Thanks for the comments.
Upvotes: 1
Views: 1662
Reputation: 67297
You commented:
@kriegaex I have all my classes under a certain package, they are
@RestController
and in many of those classes I have a required header in the method arguments, example:@RequestHeader(value = "my-header") String myHeader
You get all @RestController
classes like this:
@within(org.springframework.web.bind.annotation.RestController)
You get all classes in a certain package (and its subpackages) like this:
within(a.certain.package..*)
You can combine that into
@within(org.springframework.web.bind.annotation.RestController) &&
within(a.certain.package..*) &&
execution(* *(..))
The execution(* *(..))
part is not necessary in Spring AOP because it only supports method execution joinpoints. In AspectJ you need it because there you can also intercept method calls, constructors and other joinpoints.
If you can really rely 100% on a @RequestHeader
parameter annotation in all target methods, you can use
execution(* *(.., @org.springframework.web.bind.annotation.RequestHeader (*), ..))
and also isolate the annotation and its value as I described here with request body (just change the annotation and also adjust the rest of the code to your needs).
If you could rely on the request header parameter to always be in the same relative position in the signature, e.g. first, second, third from left or right, it would be even easier because you could directly bind the method parameter to an advice method parameter via args()
. Please let me know if that is the case and I can show you an example.
Upvotes: 1
Reputation: 1648
The pointcut could be set to a custom annotation that is used only on methods you want to be handled by the aspect. In addition to the fine control when the aspect is applied, the annotation could have parameters used by the aspect itself (effectively modifying its behavior).
To illustrate the idea, here is a small project of mine where this is used:
While aspects are powerful and very useful in many situations, in this particular case you could also use a filter.
Upvotes: 0