問
有一個Controller的方法addw(int name){},返回值為void,映射路徑是/addw,前端傳入的參數(shù)有name、id、age,現(xiàn)在希望在不改變Controller的方法的前提下,使用AOP切入一個新的方法addall(),此時,addall方法可以獲取的參數(shù)為name,有沒有什么辦法,在不改變Controller任何代碼的情況下獲取到id、age
答
在不改變Controller代碼的情況下,addall方法無法直接獲取前端傳入的id、age參數(shù)。因為這些參數(shù)是通過HTTP請求的query參數(shù)或body參數(shù)傳遞的,而AOP只能攔截Controller方法的調(diào)用,無法直接攔截HTTP請求的處理過程。
但是可以通過一些技巧來實現(xiàn)在不改變Controller任何代碼的情況下獲取到id、age參數(shù),例如:
-
使用ThreadLocal保存參數(shù):在Controller方法中將參數(shù)保存到ThreadLocal中,然后在AOP攔截的方法中獲取ThreadLocal中的參數(shù)。這種方法需要在Controller方法中加入一些額外的代碼。
-
使用HttpServletRequest獲取參數(shù):在AOP攔截的方法中,通過HttpServletRequest對象獲取請求中的參數(shù)。這種方法不需要在Controller方法中加入額外的代碼,但需要在AOP攔截的方法中添加HttpServletRequest對象參數(shù),并且需要注意參數(shù)名與請求參數(shù)名的一致性。
問
使用HttpServletRequest獲取參數(shù)的解決方案進(jìn)行舉例
答
下面是使用HttpServletRequest獲取參數(shù)的示例代碼:
Controller方法:
@RequestMapping(value = "/addw", method = RequestMethod.POST)
public void addw(@RequestParam("name") String name) {
// Controller方法中只獲取了name參數(shù)
System.out.println("Controller方法中獲取的參數(shù) name:" + name);
}
AOP攔截方法:
@Around("execution(* com.example.controller.TestController.addw(..))")
public void addall(ProceedingJoinPoint joinPoint) throws Throwable {
// 獲取HttpServletRequest對象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
// 通過HttpServletRequest對象獲取參數(shù)
String id = request.getParameter("id");
String age = request.getParameter("age");
System.out.println("AOP攔截方法中獲取的參數(shù) id:" + id);
System.out.println("AOP攔截方法中獲取的參數(shù) age:" + age);
// 調(diào)用Controller方法
joinPoint.proceed();
}
在上述代碼中,AOP攔截方法中通過RequestContextHolder獲取當(dāng)前請求的HttpServletRequest對象,然后通過調(diào)用HttpServletRequest的getParameter方法獲取請求中的參數(shù)。注意需要在AOP攔截方法中添加HttpServletRequest對象參數(shù),并且需要與請求參數(shù)名一致。同時需要注意,如果請求參數(shù)名與參數(shù)類型不一致,則會出現(xiàn)參數(shù)值為null的情況。
問
RequestContextHolder.getRequestAttributes()沒有獲取到數(shù)據(jù)
答
如果RequestContextHolder.getRequestAttributes()沒有獲取到數(shù)據(jù),可能是因為在AOP攔截方法執(zhí)行的過程中,當(dāng)前線程的請求對象已經(jīng)被清除,導(dǎo)致無法獲取請求信息。這種情況通常出現(xiàn)在異步線程池等情況下。
為了解決這個問題,可以嘗試使用RequestContextHolder.getRequestAttributes()獲取請求上下文對象,并在攔截方法中進(jìn)行非空判斷。
下面是修改后的示例代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-428052.html
@Around("execution(* com.example.controller.TestController.addw(..))")
public void addall(ProceedingJoinPoint joinPoint) throws Throwable {
// 獲取HttpServletRequest對象
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
// 請求上下文對象為空,處理異?;蛘咧苯臃祷?/span>
return;
}
HttpServletRequest request = requestAttributes.getRequest();
// 通過HttpServletRequest對象獲取參數(shù)
String id = request.getParameter("id");
String age = request.getParameter("age");
System.out.println("AOP攔截方法中獲取的參數(shù) id:" + id);
System.out.println("AOP攔截方法中獲取的參數(shù) age:" + age);
// 調(diào)用Controller方法
joinPoint.proceed();
}
在上述代碼中,我們使用RequestContextHolder.getRequestAttributes()獲取請求上下文對象,并進(jìn)行非空判斷。如果獲取到的請求上下文對象為空,我們可以根據(jù)實際情況進(jìn)行異常處理或直接返回。文章來源地址http://www.zghlxwxcb.cn/news/detail-428052.html
到了這里,關(guān)于SpringBoot(11)AOP切入方法在不改變Controller任何代碼的情況下獲取額外參數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!