我在Spring中使用基于XML的AOP,我有以下切入点:
<aop:aspect id=".." ref="..">
<aop:pointcut id="interceptController" expression="execution(ModelAndView org.springframework.web.servlet.mvc.Controller+.handleRequest(HttpServletRequest, ..))" />
<aop:around method="myAroundAdvice" pointcut-ref="interceptController" />
</aop:aspect>
我的建议如下:
public Object myAroundAdvice(ProceedingJoinPoint jp) throws Throwable {
if (someCondition) {
Object test = jp.proceed();
return test;
}
else {
return new ModelAndView("redirect:index.htm");
}
}
上面代码的问题是,如果我们进入if表达式的true子句,一切正常,但是,如果我们进入else子句,程序崩溃并出现错误:
SEVERE: Servlet.service() for servlet ... threw exception
java.lang.ClassCastException: org.springframework.web.servlet.ModelAndView cannot be cast to java.lang.Boolean
所以我在第Object test = jp.proceed
行放了一个断点,我注意到jp.proceed();
返回布尔值true
。因此,在else子句中,当我返回一个新的ModelAndView
时它会崩溃,因为它期望从建议中返回一个布尔值。
为什么地球上有一个预期从这个建议中返回的布尔值?在切入点表达式中,我指定我匹配的方法执行的返回类型是ModelAndView
,因此,proceed()
以及我的建议应该返回ModelAndView
..
我在这里缺少什么?
UPDATE:正如所指出的,我尝试打印了连接点。因此我打印了连接点及其目标:
System.out.println("jp is : " + jp.toString());
System.out.println("target is : " + jp.getTarget().toString());
访问网页时会打印以下内容:
jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(preHandle)
target is : my.packages.etc.LoginInterceptor@5b181df3
jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(postHandle)
target is : my.packages.etc.LoginInterceptor@5b181df3
jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(afterCompletion)
target is : my.packages.etc.LoginInterceptor@5b181df3
请注意,LoginInterceptor
扩展了HandlerInterceptorAdapter
类,为什么它与我的切入点匹配?由于HandlerInterceptorAdapter
位于servlet.handler
,而我在servlet.mvc.Controller+.handleRequest
上匹配。
整个stracktrace:
18-nov-2016 14:52:26 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet ... threw exception
java.lang.ClassCastException: org.springframework.web.servlet.ModelAndView cannot be cast to java.lang.Boolean
at com.sun.proxy.$Proxy32.preHandle(Unknown Source)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:865)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:112)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:612)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:503)
at java.lang.Thread.run(Thread.java:695)
答案 0 :(得分:1)
我认为你的切入点并没有拦截你的想法。由于某种原因,它似乎拦截了返回布尔值的方法。尝试在控制台上打印jp
,看看你拦截了哪种方法。
这样的切入点看起来基本没问题,但有一件事让我感到震惊:ModelAndView
不是一个完全限定的类名。也许你想改变它。