用 aspect 修改方法参数
Modify method argument with aspect
最近我正在寻找如何在启动控制器逻辑之前更改 HttpServletRequest
object 的 header 和 body,这是我找到的唯一方法实现这是一个方面,这个解决方案很好,但问题是我有很多控制器 类,我需要更改这些控制器中特定 header 的值,我有在我的方面添加了我所有的 类:
@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
所以我的问题是:
@PointCut
中有一种方法可以将正则表达式或条件表达式或类似的东西放在一行或两行中,以获得特定的 header?
我的意思是,我有很多控制器,这些控制器收到很多 header,但我只想更改一个名为 test-token
的 header 的值,我只想避免每次在我的项目中添加一个新控制器时在我的方面添加一行。
我尝试在我的方面和其他方面添加 @RequestHeader
的包,但没有任何效果。
感谢评论。
可以将切入点设置为自定义注释,该注释仅用于您希望方面处理的方法。除了应用方面时的精细控制外,注释还可以具有方面本身使用的参数(有效地修改其行为)。
为了说明这个想法,这是我的一个小项目,其中使用了它:
虽然方面在很多情况下都很强大并且非常有用,但在这种特殊情况下,您还可以使用 filter。
您发表评论:
@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
你得到所有 @RestController
类 这样的:
@within(org.springframework.web.bind.annotation.RestController)
你得到某个包(及其子包)中的所有 类,如下所示:
within(a.certain.package..*)
你可以把它组合成
@within(org.springframework.web.bind.annotation.RestController) &&
within(a.certain.package..*) &&
execution(* *(..))
execution(* *(..))
部分在 Spring AOP 中不是必需的,因为它只支持方法执行连接点。在 AspectJ 中,您需要它,因为在那里您还可以拦截方法调用、构造函数和其他连接点。
如果你真的可以在所有目标方法中 100% 依赖一个 @RequestHeader
参数注释,你可以使用
execution(* *(.., @org.springframework.web.bind.annotation.RequestHeader (*), ..))
并按照我在请求 body 中描述的 here 隔离注释及其值(只需更改注释并根据您的需要调整其余代码)。
如果您可以依赖请求 header 参数始终处于签名中相同的相对位置,例如first, second, third from left or right,这会更容易,因为您可以通过 args()
直接将方法参数绑定到通知方法参数。如果是这种情况,请告诉我,我可以给你举个例子。
最近我正在寻找如何在启动控制器逻辑之前更改 HttpServletRequest
object 的 header 和 body,这是我找到的唯一方法实现这是一个方面,这个解决方案很好,但问题是我有很多控制器 类,我需要更改这些控制器中特定 header 的值,我有在我的方面添加了我所有的 类:
@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
所以我的问题是:
@PointCut
中有一种方法可以将正则表达式或条件表达式或类似的东西放在一行或两行中,以获得特定的 header?
我的意思是,我有很多控制器,这些控制器收到很多 header,但我只想更改一个名为 test-token
的 header 的值,我只想避免每次在我的项目中添加一个新控制器时在我的方面添加一行。
我尝试在我的方面和其他方面添加 @RequestHeader
的包,但没有任何效果。
感谢评论。
可以将切入点设置为自定义注释,该注释仅用于您希望方面处理的方法。除了应用方面时的精细控制外,注释还可以具有方面本身使用的参数(有效地修改其行为)。
为了说明这个想法,这是我的一个小项目,其中使用了它:
虽然方面在很多情况下都很强大并且非常有用,但在这种特殊情况下,您还可以使用 filter。
您发表评论:
@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
你得到所有 @RestController
类 这样的:
@within(org.springframework.web.bind.annotation.RestController)
你得到某个包(及其子包)中的所有 类,如下所示:
within(a.certain.package..*)
你可以把它组合成
@within(org.springframework.web.bind.annotation.RestController) &&
within(a.certain.package..*) &&
execution(* *(..))
execution(* *(..))
部分在 Spring AOP 中不是必需的,因为它只支持方法执行连接点。在 AspectJ 中,您需要它,因为在那里您还可以拦截方法调用、构造函数和其他连接点。
如果你真的可以在所有目标方法中 100% 依赖一个 @RequestHeader
参数注释,你可以使用
execution(* *(.., @org.springframework.web.bind.annotation.RequestHeader (*), ..))
并按照我在请求 body 中描述的 here 隔离注释及其值(只需更改注释并根据您的需要调整其余代码)。
如果您可以依赖请求 header 参数始终处于签名中相同的相对位置,例如first, second, third from left or right,这会更容易,因为您可以通过 args()
直接将方法参数绑定到通知方法参数。如果是这种情况,请告诉我,我可以给你举个例子。