Spring AOP 传递控制器方法的字符串参数
Spring AOP pass String argument of a controller method
我有一个控制器 class,它有一个采用字符串参数的 RequestMapping 方法。我想通过使用 Spring AOP 传递此参数,但它失败了,我在打印值时得到空值。
尝试使用下面提供的解决方案,但它适用于地图,但不适用于字符串。
@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 class 中打印它时,我期待值 "Hello" 但打印为 null。
您应该使用 @Aroung
建议而不是 @Before
。
有关详细信息,请参阅 this answer。
A @Before
建议并不意味着操纵方法参数。在您链接到它的示例中,它只起作用,因为参数是一个可变对象,即 Map
。 String
是不可变的,但您无法对其进行编辑。
话虽如此,你该怎么办?使用专为此类事情设计的 @Around
建议。在那里你可以决定你想如何进行,例如
- 使用原始参数调用原始方法,
- 用改变的参数调用原来的方法,
- 在调用原件后and/or之前做点什么,
- 不要调用原始方法,而是 return 另一个结果,
- 在原始方法中处理异常
- 或以上任何有意义的组合(也许你有多个案例和
if-else
或 switch-case
)。
我还建议不要直接在 JoinPoint.getArgs()
的 Object[]
上工作,而是通过 [=19] 将相关方法参数绑定到命名和 type-safe 建议参数=].试试这个:
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!" });
}
}
我有一个控制器 class,它有一个采用字符串参数的 RequestMapping 方法。我想通过使用 Spring AOP 传递此参数,但它失败了,我在打印值时得到空值。
尝试使用下面提供的解决方案,但它适用于地图,但不适用于字符串。
@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 class 中打印它时,我期待值 "Hello" 但打印为 null。
您应该使用 @Aroung
建议而不是 @Before
。
有关详细信息,请参阅 this answer。
A @Before
建议并不意味着操纵方法参数。在您链接到它的示例中,它只起作用,因为参数是一个可变对象,即 Map
。 String
是不可变的,但您无法对其进行编辑。
话虽如此,你该怎么办?使用专为此类事情设计的 @Around
建议。在那里你可以决定你想如何进行,例如
- 使用原始参数调用原始方法,
- 用改变的参数调用原来的方法,
- 在调用原件后and/or之前做点什么,
- 不要调用原始方法,而是 return 另一个结果,
- 在原始方法中处理异常
- 或以上任何有意义的组合(也许你有多个案例和
if-else
或switch-case
)。
我还建议不要直接在 JoinPoint.getArgs()
的 Object[]
上工作,而是通过 [=19] 将相关方法参数绑定到命名和 type-safe 建议参数=].试试这个:
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!" });
}
}