Я использую АОП на основе XML весной, и у меня есть следующий 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>
Мой совет заключается в следующем:
public Object myAroundAdvice(ProceedingJoinPoint jp) throws Throwable {
if (someCondition) {
Object test = jp.proceed();
return test;
}
else {
return new ModelAndView("redirect:index.htm");
}
}
Проблема с приведенным выше кодом заключается в том, что все работает нормально, если мы попадаем в истинное предложение выражения if, однако, если мы попадаем в предложение 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
, он сбой, так как он ожидал, что логическое значение будет возвращено из совета.
Почему на земле есть логическое значение, которое ожидается от этого совета? В Pointcut выражении я уточнил, что возвращаемый тип исполнения метода я совпадающей ModelAndView
, следовательно, proceed()
, а также мой совет должен возвращать ModelAndView
..
Что я здесь отсутствует?
UPDATE: Как было отмечено, я попробовал напечатать joinpoint. Поэтому я напечатал 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 : [email protected]
jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(postHandle)
target is : [email protected]
jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(afterCompletion)
target is : [email protected]
Обратите внимание, что 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)
Вы проверили, какой именно метод был перехвачен? И где именно происходит «ClassCastException»? –
@PredragMaric Он соответствует методу 'handleRequest' контроллера (который является' AbstractController'). Следовательно, мой контроллер расширяет 'AbstractController' и реализует метод' handleRequestInternal'. Следовательно, я совпадаю с методом 'handleRequest', который вызовет мой метод' handleRequestInternal', если я вызову 'continue()', и еще я хочу вернуть новый 'ModelAndView', чтобы перенаправить пользователя. Что касается исключения, он бросается на 'return test;'. Я включу весь стек в мой пост. – HyperZ