Java 行为古怪的人

Java 行为古怪的人,java,spring,aop,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, ..))" /> <

我在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>
上面代码的问题是,如果我们进入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
因此,我在
objecttest=jp.procedue
行上放置了一个断点,我注意到
jp.procedue()
返回布尔值
true
。因此,在else子句中,当我返回一个新的
ModelAndView
时,它崩溃了,因为它期望从通知返回一个布尔值

究竟为什么这个建议会返回布尔值??在切入点表达式中,我指定要匹配的方法执行的返回类型为
ModelAndView
,因此,
procedure()
以及我的建议应该返回
ModelAndView

我错过了什么


更新:如前所述,我尝试打印连接点。因此,我打印了joinpoint及其目标:

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)

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


切入点本身看起来基本上没有问题,但有一点让我印象深刻:
ModelAndView
不是一个完全限定的类名。也许你想改变这一点。

你有没有检查到底截获了哪个方法?
ClassCastException
发生在哪里?@prefragmaric它匹配控制器的
handleRequest
方法(这是一个
AbstractController
)。因此,我的控制器扩展了
AbstractController
,并实现了
handleRequestInternal
方法。因此,我正在匹配
handleRequest
方法,如果我调用
procedure()
的话,该方法将调用我的
handleRequestInternal
方法,否则我想返回一个新的
ModelAndView
,以便重定向用户。关于异常,在
返回测试时抛出。我将在我的帖子中包含整个stacktrace。你说得对,我打印了
jp.getTarget().toString()
,它在我的项目中打印了一些类
LoginInterceptor
。它似乎截取了
LoginInterceptor
类的
preHandle
方法,该方法确实返回布尔值。然而,这个
LoginInterceptor
类扩展了
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
,所以我不明白为什么会截取这个方法,因为我的切入点应该只截取
servlet.mvc.Controller+
类中的
HandleRequest
,当此方法位于
servlet.handler
中时。。。请注意,我已将
model和view
更改为其完全限定名称。我假设还有另一个切入点与同一个通知方法关联,因为您在问题中显示的切入点不会截取
preHandle
postHandle
afterCompletion
等方法。请参考方法
myAroundAdvice
,检查您的方面代码以及其他地方的配置。对,我也是这么想的,但是,最初的项目没有集成AOP。我的工作是集成AOP来做各种事情。我注释掉了所有其他切入点,因此这确实是唯一的切入点,但是问题仍然存在。为了100%确定,我更改了通知的名称,并在xml文件中引用了该新名称,但是,相同的行为仍然存在,因此,我确定没有其他切入点意外地指向相同的通知。这真的很奇怪。。我也把它给我的助教看了,他也被绊倒了。我设法解决了这个问题,使用基于注释的AOP而不是基于XML的AOP,并重写了建议。谢谢你的帮助!
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)