Spring AOP环绕通知与Controller返回值问题求助
Spring @Around切面权限校验:void与ModelAndView返回值差异解析
问题场景
用Spring的@Around切面实现权限校验:权限等级不足时返回ModelAndView("error")展示错误页面;权限足够则执行原Controller方法。但遇到异常情况:当Controller方法返回值为void时,权限不足的情况下始终显示主页面,错误页面不生效;将Controller返回值改为ModelAndView后功能恢复正常。
相关代码
1. 原Controller(返回void)
@Controller public class myViewController{ @RequestMapping("myMainPage") public void myMainPage(Model model){ model.addAttribute("logoImg", "site_logo.png"); } }
2. 切面代码
@Around("execution(* com.gas..controller.*Controller.*(..))") public Object checkAuth(ProceedingJoinPoint joinPoint) throws Throwable{ // 校验用户权限等级 // ... 权限等级判断逻辑 Object resultObject = null; if (authLevel > 0){ resultObject = joinPoint.proceed(); } else { // 权限不足,返回错误页面 resultObject = new ModelAndView("error"); } return resultObject; // 原代码漏写return,补上后才能正常传递切面返回值 }
3. 解决方案Controller(返回ModelAndView)
@Controller public class myViewController{ @RequestMapping("myMainPage") public ModelAndView myMainPage(Model model){ model.addAttribute("logoImg", "site_logo.png"); return new ModelAndView("myMainPage"); } }
差异原因解析
Spring MVC对Controller不同返回值的处理逻辑存在本质区别,这是导致切面行为不一致的核心:
返回
void时的处理逻辑- 当Controller方法返回
void,Spring MVC默认会根据请求路径自动解析视图名称(比如请求myMainPage,就会匹配名为myMainPage的视图)。 - 此时切面返回的
ModelAndView("error")会被Spring忽略——因为Spring认为void意味着Controller已经自行完成了响应处理(比如直接输出响应流),不会再处理切面返回的视图对象,最终还是按默认规则渲染主页面。
- 当Controller方法返回
返回
ModelAndView时的处理逻辑- 当Controller方法返回
ModelAndView,Spring MVC会直接使用这个返回值来确定要渲染的视图,包括切面中替换后的ModelAndView("error")。 - 切面通过
joinPoint.proceed()拿到原方法返回的ModelAndView,或者直接返回自定义的ModelAndView,Spring都会优先使用这个返回值,因此权限不足时能正确展示错误页面。
- 当Controller方法返回
内容的提问来源于stack exchange,提问作者gf160
相关产品推荐
相关产品推荐

