【问题标题】:Spring AOP pass String argument of a controller methodSpring AOP 传递控制器方法的字符串参数
【发布时间】:2019-05-14 14:19:21
【问题描述】:

我有一个控制器类,它有一个采用字符串参数的 RequestMapping 方法。我想通过使用 Spring AOP 来传递这个参数,但它失败了,当我打印值时我得到空值。

尝试使用以下提供的解决方案,但它使用地图而不是字符串。

Spring AOP pass argument of a controller method

@Controller
public class WelcomeController {
    @Autowired
    private FamilyService familyService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView welcomePage(String welcomeMessage) {
        FamilyVO allFamilyMembers = familyService.getAllFamilyMembers();
        ModelAndView modelAndView = new ModelAndView("Index", "family", allFamilyMembers);
        List<String> familyMemberAges = new ArrayList<String>();
        for (int i = 0; i <= 100; i++) {
            familyMemberAges.add("" + i);
        }
        modelAndView.addObject("familyMemberAges", familyMemberAges);
        System.out.println(welcomeMessage);
        return modelAndView;
    }
}
@Component
@Aspect
public class WelcomeControllerAspect {
    @Before("execution(* com.kalavakuri.webmvc.web.controller.WelcomeController.welcomePage(..))")
    public void beforeWelcomePage(JoinPoint joinPoint) {
        joinPoint.getArgs()[0] = "Hellow";
        System.out.println(joinPoint.getArgs().length);
        System.out.println("Before welcomepage");
    }
}

当我在 Controller 类中打印它但打印 null 时,我期待值“Hello”。

【问题讨论】:

    标签: spring spring-mvc spring-aop spring-aspects


    【解决方案1】:

    @Before 建议并不意味着操纵方法参数。在您链接到它的示例中,仅因为参数是一个可变对象,即Map 而起作用。 String 是不可变的,但是您不能编辑它。

    说了这么多,你该怎么办?使用专为此类事情设计的@Around 建议。在那里你可以决定你想如何进行,例如

    • 使用原始参数调用原始方法,
    • 使用更改的参数调用原始方法,
    • 在调用原件之前和/或之后做一些事情,
    • 不要调用原来的方法,而是返回另一个结果,
    • 在原始方法中处理异常
    • 或以上任何有意义的组合(也许您有多个案例和if-elseswitch-case)。

    我还建议不要直接在JoinPoint.getArgs()Object[] 上工作,而是通过args() 将相关方法参数绑定到命名和类型安全的通知参数。试试这个:

    package de.scrum_master.aspect;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    public class WelcomeControllerAspect {
      @Around(
        "execution(* com.kalavakuri.webmvc.web.controller.WelcomeController.welcomePage(..)) && " +
        "args(welcomeMessage)"
      )
      public Object beforeWelcomePage(ProceedingJoinPoint joinPoint, String welcomeMessage) throws Throwable {
        System.out.println(joinPoint + " -> " + welcomeMessage);
        return joinPoint.proceed(new Object[] { "Hello AOP!" });
      }
    }
    

    【讨论】:

      【解决方案2】:

      您应该使用@Aroung 建议而不是@Before。 详情请见this answer

      【讨论】:

        猜你喜欢
        • 2011-06-23
        • 1970-01-01
        • 1970-01-01
        • 2021-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多