Homepage-Webhilfe Event-Banner

Fehlerbehandlung

In diesem Thema wollen wir uns damit beschäftigen, wie Sie in Java-Webanwendungen HTTP- und Ausnahme-Fehler abfangen können, um somit z. B. Ihren Besuchern beim Auftreten eines Fehlers, eine eigene Fehlerseite anzeigen zu können (und nicht die Standardseiten von Ihrem Webserver). Natürlich können Sie diese Möglichkeit auch dazu verwenden, Fehler zu protokollieren.


Im Protokoll HTTP (und auch bei HTTPS) sind sogenannte Statuscodes implementiert. Bei jeder HTTP-Antwort sendet der Server an den Client einen solchen Statuscode mit. In den meisten Fällen wir der Code 200 OK zurückgeschickt, welcher signalisiert, dass die angefragte Ressource gefunden wurde und der Inhalt zurückgeschickt wird. Die Liste der verfügbaren Statuscodes ist lang, weshalb wir uns hier vorerst mal nur mit den Statuscodes 403 Forbidden und 404 Not Found auseinandersetzen wollen. Der Code 403 weist darauf hin, dass der Zugriff auf die Ressource auf Grund einer fehlenden Berechtigung nicht möglich ist. Einen solchen Fehlercode könnten Sie bspw. in einem Filter zurückgeben, wenn ein Zugriff auf den Admin-Bereich vorgenommen wird, jedoch nicht der Administrator angemeldet ist. Den Statuscode 404 hat vermutlich schon jeder gesehen und besagt einfach nur, dass die angefragte Ressource nicht (mehr) verfügbar ist. Im Internet sind u. a. oftmals Links zu finden, welche auf eine Seite verweisen, welche nicht mehr existiert. So ein Link wird dann auch als toter Link bezeichnet.

Zurück zu den Java-Webanwendungen: Wenn Sie beim Auftreten eines bestimmten Statuscodes auf eine bestimmte Seite (dabei kann es sich auch um ein Servlet handeln) verweisen wollen, dann müssen Sie lediglich eine Konfiguration im Deployment Descriptor durchführen. Dafür benötigen Sie das XML-Element error-page, welchem Sie die XML-Elemente error-code und location unterordnen. Dies sieht dann z. B. so aus:

<error-page>
    <error-code>404</error-code>
    <location>/ErrorServlet</location>
</error-page>

Innerhalb eines Servlets können Sie mit der Funktion getAttribute() des HttpServletRequest-Objekts den „fehlerhaften“ Statuscode abrufen. Als Attribut-Name müssen Sie javax.servlet.error.status_code übergeben.

Beim Aufrufen des folgenden Beispiels werden Sie als erstes auf das Servlet ErrorServlet umgeleitet, da es kein Servlet für das Wurzelverzeichnis gibt. Es handelt sich daher also um einen 404-Fehler. Beim Versuch des Aufrufs von AdminServlet werden Sie ebenfalls wieder auf ErrorServlet umgeleitet. Dieses Mal wird Ihnen jedoch der Fehlercode 403 angezeigt.

Servlet (ErrorServlet.java):

package de.hwh.bsp.httpfehler;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ErrorServlet extends HttpServlet
{
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        // Ausgabe als Text-Datei
        response.setContentType("text/plain;charset=UTF-8");
        
        // Ausgabe durchführen
        PrintWriter out = response.getWriter();
        out.println("HTTP-Fehler-Code: " + request.getAttribute("javax.servlet.error.status_code"));
        out.close();
    }
}

Servlet (AdminServlet.java):

package de.hwh.bsp.httpfehler;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AdminServlet extends HttpServlet
{
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        response.sendError(403);
    }
}

Konfiguration (web.xml):

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <servlet>
        <servlet-name>ErrorServlet</servlet-name>
        <servlet-class>de.hwh.bsp.httpfehler.ErrorServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>AdminServlet</servlet-name>
        <servlet-class>de.hwh.bsp.httpfehler.AdminServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ErrorServlet</servlet-name>
        <url-pattern>/ErrorServlet</url-pattern>
    </servlet-mapping>
    <error-page>
        <error-code>403</error-code>
        <location>/ErrorServlet</location>
    </error-page>
    <error-page>
        <error-code>404</error-code>
        <location>/ErrorServlet</location>
    </error-page>
    <servlet-mapping>
        <servlet-name>AdminServlet</servlet-name>
        <url-pattern>/AdminServlet</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>
VorschauDownload

Übrigens: Ein weiterer gängiger Statuscode ist 500 Internal Server Error, welcher in den meisten Fällen auf Grund einer fehlerhaften Konfiguration des Webservers erscheint.


In Java sollten Sie, so wie in anderen Programmiersprachen auch, versuchen, Fehler (vor allem Ausnahmefehler) im Programm so gut wie möglich abzufangen. Trotzdem kommt es immer wieder vor, dass Sie vergessen, einen Ausnahmefehler (engl. exception) abzufangen. Dies ist auch nicht weiter schlimm, da vom Servlet-Container alle Ausnahmen abgefangen werden. Da in der Regel in so einem Fall jedoch eine Art von Debug-Informationen angezeigt werden, welche die Besucher nicht sehen sollten, sollten diese Art von Fehlern ebenfalls abgefangen werden. Auch hier kann dazu der Deployment Descriptor verwendet werden.

Im Deployment Descriptor wird auch hier das XML-Element error-page verwendet. Diesem wird nun das exception-type- und das bereits bekannte location-Element untergeordnet.

<error-page>
    <exception-type>java.io.IOException</exception-type>
    <location>/ErrorServlet</location>
</error-page>

Im „Fehler-Servlet“ können wir mit der Funktion getAttribute() und dem Attributnamen javax.servlet.error.exception_type den Typ der Ausnahme abfragen. Mit dem Attribut javax.servlet.error.message kann die übergebene Meldung abgefragt werden.

Im folgenden Beispiel wird auf der Startseite (StartServlet.java) manuell (und lediglich zu Demonstrationszwecken) eine IO-Ausnahme (IOException) geworfen. Dadurch leitet uns der Servlet-Container auf das Servlet ErrorServlet um, in welchem die Informationen zur Ausnahme angezeigt werden.

Servlet (ErrorServlet.java):

package de.hwh.bsp.ausnahmefehler;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ErrorServlet extends HttpServlet
{
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        // Ausgabe als Text-Datei
        response.setContentType("text/plain;charset=UTF-8");
        
        // Ausgabe durchführen
        PrintWriter out = response.getWriter();
        out.println("Exception-Typ: " + request.getAttribute("javax.servlet.error.exception_type"));
        out.println("Meldung: " + request.getAttribute("javax.servlet.error.message"));
        out.close();
    }
}

Servlet (StartServlet.java):

package de.hwh.bsp.ausnahmefehler;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class StartServlet extends HttpServlet
{
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        throw new IOException("Fehler beim Zugriff auf die Ressource");
    }
}

Konfiguration (web.xml):

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <servlet>
        <servlet-name>ErrorServlet</servlet-name>
        <servlet-class>de.hwh.bsp.ausnahmefehler.ErrorServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>StartServlet</servlet-name>
        <servlet-class>de.hwh.bsp.ausnahmefehler.StartServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ErrorServlet</servlet-name>
        <url-pattern>/ErrorServlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>StartServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <error-page>
        <exception-type>java.io.IOException</exception-type>
        <location>/ErrorServlet</location>
    </error-page>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>
VorschauDownload
Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen OK