周围的建议行为奇怪

时间:2016-11-18 13:20:49

标签: java spring aop

我在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)

1 个答案:

答案 0 :(得分:1)

我认为你的切入点并没有拦截你的想法。由于某种原因,它似乎拦截了返回布尔值的方法。尝试在控制台上打印jp,看看你拦截了哪种方法。

这样的切入点看起来基本没问题,但有一件事让我感到震惊:ModelAndView不是一个完全限定的类名。也许你想改变它。