Reputation: 2891
I'm using XML based AOP in Spring, and i have the following pointcut:
<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>
My advice is the following:
public Object myAroundAdvice(ProceedingJoinPoint jp) throws Throwable {
if (someCondition) {
Object test = jp.proceed();
return test;
}
else {
return new ModelAndView("redirect:index.htm");
}
}
The problem with the above code is that everything works fine if we get into the true clause of the if expression, however, if we get into the else clause, the program crashes with error:
SEVERE: Servlet.service() for servlet ... threw exception
java.lang.ClassCastException: org.springframework.web.servlet.ModelAndView cannot be cast to java.lang.Boolean
So i put a breakpoint on the line Object test = jp.proceed
, and i noticed that jp.proceed();
returns the boolean true
. Hence, in the else clause, when i return a new ModelAndView
it crashes since it expected a boolean to be returned from the advice..
Why on earth is a boolean expected to be returned from this advice?? In the pointcut expression i specified that the return type of the method execution i am matching is ModelAndView
, hence, proceed()
as well as my advice should return a ModelAndView
..
What am i missing here?
UPDATE: As pointed out, I tried printing the joinpoint. Therefore i printed the joinpoint as well as its target :
System.out.println("jp is : " + jp.toString());
System.out.println("target is : " + jp.getTarget().toString());
This prints the following when visiting a webpage :
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
Note that LoginInterceptor
extends the HandlerInterceptorAdapter
class, so why is it matching with my pointcut? Because HandlerInterceptorAdapter
is in servlet.handler
while i match on servlet.mvc.Controller+.handleRequest
.
Entire 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)
Upvotes: 2
Views: 723
Reputation: 67317
I think your pointcut does not intercept what you think it does. For some reason it seems to intercept methods returning boolean values. Try printing jp
on the console and see which method you have intercepted.
The pointcut as such looks basically okay, but one thing strikes me: ModelAndView
is not a fully qualified class name. Maybe you want to change that.
Upvotes: 1