Heute werden wir uns mit der Servlet-Ausnahme und der Fehlerbehandlung befassen. Vor einiger Zeit habe ich einen Beitrag über Ausnahmebehandlung in Java geschrieben, aber wenn es um Webanwendungen geht, benötigen wir mehr als nur die normale Ausnahmebehandlung in Java.
Servlet-Ausnahme
Wenn Sie es bemerken, werfen die Methoden doGet() und doPost() javax.servlet.ServletException
und IOException
. Schauen wir mal, was passiert, wenn wir diese Ausnahme aus unserer Anwendung werfen. Ich werde ein einfaches Servlet schreiben, das die ServletException wirft.
package com.journaldev.servlet.exception;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/MyExceptionServlet")
public class MyExceptionServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
throw new ServletException("GET method is not supported.");
}
}
Wenn wir dieses Servlet jetzt über den Browser mit der GET-Methode aufrufen, erhalten wir eine Antwort wie im folgenden Bild. Da der Browser nur HTML versteht, verarbeitet der Servlet-Container die Ausnahme und generiert eine HTML-Antwort. Diese Logik ist spezifisch für den Servlet-Container. Ich verwende Tomcat und erhalte diese Fehlerseite. Wenn Sie andere Server wie JBoss oder Glassfish verwenden, erhalten Sie möglicherweise eine andere HTML-Fehlerantwort. Das Problem bei dieser Antwort ist, dass sie für den Benutzer keinen Wert hat. Außerdem zeigt sie unsere Anwendungs-Klassen und Serverdetails an, was für den Benutzer keinen Sinn ergibt und aus Sicherheitssicht nicht gut ist.
Servlefehler
I am sure you must have seen 404 error when you are trying to hit a URL that doesn’t exists. Let’s see how our servlet container responds to 404 error. If we send request for an invalid URL, we get response HTML like below image. Again it’s a generic HTML generated by server on our application behalf and hold little to no value to the user.
Servlet-Ausnahme und Fehlerbehandlung
Die Servlet-API bietet Unterstützung für benutzerdefinierte Ausnahme- und Fehlerhandler-Servlets, die wir im Bereitstellungsdeskriptor konfigurieren können. Der gesamte Zweck dieser Servlets besteht darin, die von der Anwendung ausgelöste Ausnahme oder den Fehler zu behandeln und dem Benutzer eine nützliche HTML-Antwort zu senden. Wir können einen Link zur Startseite der Anwendung bereitstellen oder einige Details angeben, um dem Benutzer mitzuteilen, was schief gelaufen ist. Zunächst müssen wir also ein benutzerdefiniertes Ausnahme- und Fehlerhandler-Servlet erstellen. Wir können mehrere Ausnahme- und Fehlerhandler-Servlets für die Anwendung haben, aber aus Gründen der Einfachheit werde ich ein einzelnes Servlet erstellen und es sowohl für Ausnahmen als auch für Fehler verwenden. AppExceptionHandler.java
package com.journaldev.servlet.exception;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/AppExceptionHandler")
public class AppExceptionHandler extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processError(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
processError(request, response);
}
private void processError(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// Analysieren der Servlet-Ausnahme
Throwable throwable = (Throwable) request
.getAttribute("javax.servlet.error.exception");
Integer statusCode = (Integer) request
.getAttribute("javax.servlet.error.status_code");
String servletName = (String) request
.getAttribute("javax.servlet.error.servlet_name");
if (servletName == null) {
servletName = "Unknown";
}
String requestUri = (String) request
.getAttribute("javax.servlet.error.request_uri");
if (requestUri == null) {
requestUri = "Unknown";
}
// Setzen des Antwortinhalts-Typs
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.write("Exception/Error Details ");
if(statusCode != 500){
out.write("Error Details
");
out.write("Status Code:"+statusCode+"
");
out.write("Requested URI:"+requestUri);
}else{
out.write("Exception Details
");
out.write("- Servlet Name:"+servletName+"
");
out.write("- Exception Name:"+throwable.getClass().getName()+"
");
out.write("- Requested URI:"+requestUri+"
");
out.write("- Exception Message:"+throwable.getMessage()+"
");
out.write("
");
}
out.write("
");
out.write("Home Page");
out.write("");
}
}
Lasst uns sehen, wie wir es im Bereitstellungsdeskriptor konfigurieren können, und dann werden wir verstehen, wie seine Implementierung aussieht und wie es funktioniert.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>ServletExceptionHandling</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<error-page>
<error-code>404</error-code>
<location>/AppExceptionHandler</location>
</error-page>
<error-page>
<exception-type>javax.servlet.ServletException</exception-type>
<location>/AppExceptionHandler</location>
</error-page>
</web-app>
Wie Sie sehen können, ist es sehr einfach, Ausnahmehandler-Servlets für die Anwendung mithilfe des error-page-Elements zu spezifizieren. Jedes error-page-Element sollte entweder ein error-code– oder ein exception-type-Element haben. Wir definieren das Ausnahmehandler-Servlet im location-Element. Basierend auf obiger Konfiguration, wenn die Anwendung einen 404-Fehler oder eine ServletException auslöst, wird sie vom AppExceptionHandler-Servlet behandelt. Wenn ein solcher Ausnahmefall und Fehler auftritt, ruft der Servlet-Container die entsprechende HTTP-Methode des Ausnahmehandler-Servlets auf und übergibt das Anfrage- und Antwortobjekt. Beachten Sie, dass ich die Implementierung sowohl der doGet()- als auch der doPost()-Methoden bereitgestellt habe, damit sie GET- und POST-Anfragen verarbeiten und eine gemeinsame Methode verwenden kann, um sie zu verarbeiten. Bevor der Servlet-Container das Servlet aufruft, um die Ausnahme zu behandeln, setzt er einige Attribute in die Anfrage, um nützliche Informationen über die Ausnahme zu erhalten. Einige davon sind javax.servlet.error.exception, javax.servlet.error.status_code, javax.servlet.error.servlet_name und javax.servlet.error.request_uri. Für Ausnahmen ist der Statuscode immer 500, was dem „Internen Serverfehler“ entspricht, für andere Arten von Fehlern erhalten wir unterschiedliche Fehlercodes wie 404, 403 usw. Basierend auf dem Statuscode stellt unsere Implementierung unterschiedliche Arten von HTML-Antworten für den Benutzer bereit. Es bietet auch einen Hyperlink zur Startseite der Anwendung. Wenn wir nun unser Servlet aufrufen, das eine ServletException auslöst, erhalten wir eine Antwort wie im folgenden Bild. Wenn wir versuchen, auf eine ungültige URL zuzugreifen, was zu einer 404-Antwort führt, erhalten wir eine Antwort wie im folgenden Bild.
Sieht es nicht gut aus und hilft dem Benutzer, leicht zu verstehen, was passiert ist, und bietet ihm einen Weg, zum richtigen Ort zu gelangen? Es vermeidet auch das Senden von anwendungssensiblen Informationen an den Benutzer. Wir sollten immer Ausnahmehandler für unsere Webanwendung haben. Wenn Sie Laufzeitfehler und alle anderen Ausnahmen in einem einzigen Ausnahmehandler behandeln möchten, können Sie exception-type als Throwable angeben.
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/AppExceptionHandler</location>
</error-page>
Wenn es mehrere Einträge für Fehlerseiten gibt, sagen wir einen für Throwable und einen für IOException, und die Anwendung wirft eine FileNotFoundException, dann wird sie vom Fehlerhandler von IOException behandelt. Sie können auch eine JSP-Seite als Ausnahmehandler verwenden, geben Sie einfach den Speicherort der JSP-Datei an, anstatt ein Servlet-Mapping bereitzustellen. Das ist alles für die Ausnahmebehandlung von Servlets in Webanwendungen, ich hoffe, es hat Ihnen gefallen.
Laden Sie das Beispielprojekt zur Servlet-Ausnahmebehandlung herunter
Sehen Sie sich auch andere Artikel in dieser Serie an: