2016-11-18 3 views
2

ich im Frühjahr XML-basierte AOP verwenden, und ich habe folgendes pointcut:Around Beratung verhalten seltsam

<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> 

Mein Rat ist folgender:

public Object myAroundAdvice(ProceedingJoinPoint jp) throws Throwable { 
    if (someCondition) { 
     Object test = jp.proceed(); 
     return test; 
    } 
    else { 
     return new ModelAndView("redirect:index.htm"); 
    } 
} 

Das Problem mit dem obigen Code ist, dass alles gut funktioniert, wenn wir in die wahre Klausel des if-Ausdrucks kommen, wenn wir jedoch in die else-Klausel kommen, stürzt das Programm mit folgendem Fehler ab:

SEVERE: Servlet.service() for servlet ... threw exception 
java.lang.ClassCastException: org.springframework.web.servlet.ModelAndView cannot be cast to java.lang.Boolean 

Also legte ich einen Haltepunkt auf der Linie Object test = jp.proceed, und ich bemerkte, dass jp.proceed(); die boolean true zurückgibt. Daher stürzt in der else-Klausel, wenn ich eine neue zurückgeben es ab, da erwartet, dass ein Boolean von der Beratung zurückgegeben wird.

Warum in der Welt ist ein boolean erwartet, von diesem Rat zurückgegeben werden? i angegeben Im pointcut Ausdruck, dass der Rückgabetyp der Methode Ausführung i passend bin, ist ModelAndView daher proceed() sowie mein Rat, den ich ein ModelAndView ..

Was bin hierher zurückkommen sollte?


UPDATE: Wie erwähnt, habe ich versucht, die joinpoint Druck. Daher gedruckt ich die joinpoint sowie sein Ziel:

System.out.println("jp is : " + jp.toString()); 
System.out.println("target is : " + jp.getTarget().toString()); 

Dies druckt nach dem, wenn eine Webseite besuchen:

jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(preHandle) 
target is : [email protected] 

jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(postHandle) 
target is : my.packages.etc.LoginI[email protected] 

jp is : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(afterCompletion) 
target is : [email protected] 

Beachten Sie, dass LoginInterceptor erweitert die HandlerInterceptorAdapter Klasse, also warum ist es passend mit meinem pointcut ? Weil HandlerInterceptorAdapter ist in servlet.handler während ich auf servlet.mvc.Controller+.handleRequest übereinstimmen.


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) 
+0

Haben Sie überprüft, welche Methode genau abgefangen wurde? Und wo genau passiert die 'ClassCastException'? –

+0

@PredragMaric Es entspricht der 'handleRequest' Methode des Controllers (was ein' AbstractController' ist). Daher erweitert mein Controller den 'AbstractController' und implementiert die' handleRequestInternal' Methode. Daher stimme ich mit der Methode 'handleRequest' überein, die meine Methode' handleRequestInternal' aufruft, wenn ich 'proceed() 'rufe, und ansonsten würde ich eine neue' ModelAndView' zurückgeben, um den Benutzer umzuleiten. In Bezug auf die Ausnahme wird es auf "Return Test;" geworfen. Ich werde den gesamten StackTrace in meinen Beitrag aufnehmen. – HyperZ

Antwort

1

Ich denke, Ihre pointcut abfangen nicht, was Sie denken, es tut. Aus irgendeinem Grund scheint es Methoden abzufangen, die boolesche Werte zurückgeben. Versuchen Sie, jp auf der Konsole zu drucken, und sehen Sie, welche Methode Sie abgehört haben.

Der Pointcut als solcher sieht grundsätzlich gut aus, aber eine Sache fällt mir auf: ModelAndView ist kein voll qualifizierter Klassenname. Vielleicht willst du das ändern?

+0

Sie haben recht, ich habe 'jp.getTarget(). ToString()' ausgedruckt, was eine Klasse 'LoginInterceptor' in meinem Projekt ausgibt.Es scheint, dass es die "preHandle" -Methode der "LoginInterceptor" -Klasse abfängt, die in der Tat einen booleschen Wert zurückgibt. Diese 'LoginInterceptor' Klasse erweitert jedoch' org.springframework.web.servlet.handler.HandlerInterceptorAdapter', weshalb ich nicht verstehe, warum diese Methode abgefangen wird, da mein Pointcut nur 'HandleRequest' von' servlet.mvc abfangen soll. Controller + 'classes, während diese Methode in' servlet.handler' steht ... Beachten Sie, dass ich 'ModelAndView' in den vollständig qualifizierten Namen geändert habe. – HyperZ

+0

Ich nehme an, es gibt einen anderen Pointcut, der der gleichen Methode zugeordnet ist, weil der, den Sie in Ihrer Frage zeigen, keine Methoden wie 'preHandle',' postHandle' oder 'afterCompletion' abfängt. Bitte überprüfen Sie Ihren Seitencode sowie Ihre Konfiguration für andere Orte, die sich auf die Methode 'myAroundAdvice' beziehen. – kriegaex

+0

Richtig, das habe ich auch gedacht, aber das ursprüngliche Projekt hat AOP nicht integriert. Meine Aufgabe ist es, AOP zu integrieren, um alle möglichen Dinge zu erledigen. Ich habe alle anderen Punktzahlen auskommentiert, so dass dies wirklich der einzige Punkt ist, das Problem besteht jedoch weiterhin. Um 100% sicher zu sein, habe ich den Namen des Hinweises geändert, und in meiner XML-Datei, die auf diesen neuen Namen verweist, bleibt das gleiche Verhalten bestehen, daher bin ich mir sicher, dass es keinen anderen Punktcode gibt, der versehentlich auf denselben verweist Rat. Das ist wirklich komisch. Ich habe es auch meinem Assistenten gezeigt und er ist auch gestolpert. – HyperZ