Diesmal gibt es einen kurzen Beitrag aus der Java Ecke, da mich das Thema beschäftigte und ich eine Lösung suchen musste, um das Problem zu lösen. Hinterher ist man immer schlauer und daran lasse ich euch gerne teil haben 😉
Die Konfiguration des Deployment Descriptors ist ganz schön umfangreich und so kann man da gerne mal den Überblick verlieren. Ich stand vor dem Problem, dass ein Filter nicht greifen wollte, wenn ein Status Code ungleich 200 gesendet wurde.
Aber eins nach dem anderen. Möchte man im Fehlerfall eine angepasste Fehlerseite ausliefern kann man zu dem jeweiligen Fehlercode eine Seite angeben. Dies passiert mit einem Codestück ähnlich diesem:
<error-page> <error-code>404</error-code> <location>/error404.html</location> </error-page>
Der Error-Code
entspricht dem Statuscode und die Location ist die Seite, die statt der Standard-Fehlerseite ausgeliefert werden soll.
Der Servlet-Filter wird vor und/oder nach dem eigentlichen Servlet, das den entsprechenden Request verarbeitet gesetzt. Es handelt sich dabei einfach um eine Klasse die von Filter abgeleitet werden muss. In der web.xml wird ein solcher Filter in etwa so verankert:
<!-- define the filter --> <filter> <filter-name>MyMightyFilter</filter-name> <filter-class>org.example.util.filters.MightyFilter</filter-class> </filter> <!-- now map this filter to a URL-pattern --> <filter-mapping> <filter-name>MyMightyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Der Filter behandelt nun alle Urls und kann mit den Request und Response Daten etwas tun. Jetzt ist der Filter aber auch noch auf bestimmte Dispatcher eingeschränkt. Nur wenn ein Request oder Forward ausgeführt wird soll er aktiv werden. Somit sieht das Mapping ein wenig anders aus:
<filter-mapping> <filter-name>MyMightyFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>
Nun kommen wir zu dem eigentlich Problem. Der Filter greift in diesem Fall nicht, wenn eine ErrorCode-Seite (wie oben definiert) ausgeliefert werden soll. Wenn bspw. die Verzeichnisse im Request umgeschrieben werden ist die Auswirkung recht eindeutig. Die Fehlerseite kann ihrerseits nicht gefunden werden. Wo liegt nun das Problem?
Die Lösung ist recht einfach. Man muss dem filter Mapping auch noch den ERROR-Dispatcher mitgeben, denn genau der wird betrachtet, wenn eine Fehlerseite ausgeliefert werden soll. Eigentlich ist das logisch und auch sinnvoll, da man so im Fehlerfall einen Filter umgehen kann. Der korrekte Code für das Problem lautet somit:
<filter-mapping> <filter-name>MyMightyFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>