@ControllerAdvice nicht ausgelöst

8

Ich arbeite an einer Spring MVC / Webflow-Anwendung (Version 3.2) und versuche, die Ausnahmebehandlung zu erhalten, wo ich eine benutzerdefinierte Ausnahmebedingungsnachricht in einer Protokolldatei und error.jsp ausgeben kann. Das Problem, das ich habe, ist, dass der Exception Handler nicht gefeuert wird. Ich habe die folgende Klasse erstellt und mit " @ControllerAdvice " versehen und sie in das gleiche Paket wie mein Controller eingefügt, der die Ausnahme auslöst:

%Vor%

und fügte der mvc-config-Datei Folgendes hinzu:

%Vor%

Und in meiner app-config-Datei enthalten:

%Vor%

Irgendwelche Ideen, warum das nicht funktioniert?

    
user676567 19.02.2014, 15:18
quelle

2 Antworten

8

Das <mvc:annotation-driven/> -Element registriert implizit eine ExceptionHandlerExceptionResolver -Bohne. Diese Klasse hat eine initExceptionHandlerAdviceCache() -Methode, die Beans im Kontext durchsucht, um diejenigen zu finden, deren Klassentyp mit @ControllerAdvice annotiert ist.

Dies geschieht, indem zuerst ControllerAdviceBean.findAnnotatedBeans(ApplicationContext) . Intern verwendet diese Methode ApplicationContext#getBeanDefinitionNames() . Das Javadoc dieser Methode besagt

  

Berücksichtigt keine Hierarchie, an der diese Fabrik teilnehmen kann

Um zu verdeutlichen, was das bedeutet. Wenn Sie in Ihrem Implementierungsdeskriptor ein ContextLoaderListener deklarieren, lädt es das, was wir als Root oder Anwendung ApplicationContext bezeichnen, und stellt es in ServletContext zur Verfügung. Wenn Sie dann DispatcherServlet deklarieren, erstellt es sein eigenes Servlet ApplicationContext und verwendet jedes ApplicationContext , das es in den ServletContext -Attributen findet, die von ContextLoaderListener als übergeordnetes Objekt in diesen Kontext geladen wurden . Die Hierarchie sieht so aus

%Vor%

Jedes ApplicationContext hat Zugriff auf die Beans im übergeordneten Kontext, aber nicht umgekehrt.

Die obige Methode wählt die Beans nicht in übergeordneten Kontexten aus und hat daher nur Zugriff auf Beans in der aktuellen ApplicationContext ( BeanFactory wirklich).

Als solches, wenn Ihr

%Vor%

wird in einem root ApplicationContext deklariert, wie ich von dem Namen app-config annehmen werde, aber das

%Vor%

wird im Servlet ApplicationContext deklariert, wieder unter der Annahme von mvc-config , dann findet die ExceptionHandlerExceptionResolver Suche nach @ControllerAdvice Beans keine. Es sucht nach Beans im Servlet-Kontext, aber sie sind nicht da, sie sind im Root-Kontext.

    
Sotirios Delimanolis 19.02.2014 23:29
quelle
0

Falls jemand anderes auf ein Problem wie dieses stößt - ich habe einen Fehler gefunden, den ich hatte.

Ich hatte nur ein RequestMapping ( Ссылка )

In einem InterceptorController habe ich in der PreHandle-Methode explizit eine Exception geworfen - & gt; throw new MyCustomException("error","error.jsp") , um mein @ControllerAdvice Exception handling zu testen.

Als ich zu Ссылка ging, würde ich sehen, dass der Interceptor-Controller aufgerufen wird, meine benutzerdefinierte Ausnahme wird ausgelöst, aber die @ControllerAdvice -Klasse mit meinem @ExceptionHandler(MyCustomException.class) wurde nie aufgerufen.

Ich habe ein @RequestMapping(value="/") hinzugefügt und es hat meine Probleme gelöst. Da ich versuchte, zu einem URI zu gehen, dem keine @RequestMapping zugeordnet war, bekam ich eine 'NoHandlerFoundException' , die meine Exception durch Aufblasen kurzgeschlossen hat.

Kurz gesagt, stellen Sie sicher, dass der URI, auf den Sie zugreifen möchten, eine @RequestMapping zugeordnet hat, oder verwenden Sie eine Methode in Ihrer ExceptionHandler -Klasse, um mit der NoHandlerFoundException umzugehen.

Hoffe, das hilft.

    
Brian Beech 10.08.2015 18:25
quelle