Aujourd’hui, nous examinerons l’exception de servlet et la gestion des erreurs. Il y a quelque temps, j’ai écrit un article sur la Gestion des exceptions en Java, mais quand il s’agit d’une application web, nous avons besoin de plus que la gestion normale des exceptions en Java.
Exception de Servlet
Si vous remarquez, les méthodes doGet() et doPost() lèvent javax.servlet.ServletException
et IOException
, voyons ce qui se passe lorsque nous lançons ces exceptions depuis notre application. Je vais écrire un simple servlet qui lèvera ServletException.
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.");
}
}
Maintenant, lorsque nous invoquons ce servlet via le navigateur avec la méthode GET, nous obtenons une réponse comme sur l’image ci-dessous. Puisque le navigateur comprend uniquement HTML, lorsque notre application lance une exception, le conteneur de servlet traite l’exception et génère une réponse HTML. Cette logique est spécifique au conteneur de servlet. J’utilise Tomcat et j’obtiens cette page d’erreur. Si vous utilisez d’autres serveurs comme JBoss ou Glassfish, vous pourriez obtenir une réponse HTML d’erreur différente. Le problème avec cette réponse est qu’elle n’a aucune valeur pour l’utilisateur. De plus, elle affiche les classes de notre application et les détails du serveur à l’utilisateur, ce qui n’a aucun sens pour lui et ce n’est pas bon du point de vue de la sécurité.
Erreur de servlet
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.
Exception de servlet et gestion des erreurs
L’API Servlet fournit un support pour les servlets de gestion des exceptions et des erreurs personnalisés que nous pouvons configurer dans le descripteur de déploiement. Le but de ces servlets est de gérer l’exception ou l’erreur générée par l’application et d’envoyer une réponse HTML utile à l’utilisateur. Nous pouvons fournir un lien vers la page d’accueil de l’application ou quelques détails pour informer l’utilisateur de ce qui s’est mal passé. Donc, tout d’abord, nous devons créer un servlet de gestion des exceptions et des erreurs personnalisé. Nous pouvons avoir plusieurs servlets de gestion des exceptions et des erreurs pour l’application, mais pour des raisons de simplicité, je vais créer un seul servlet et l’utiliser à la fois pour les exceptions et les erreurs. 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 {
// Analyser l'exception de servlet
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";
}
// Définir le type de contenu de la réponse
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("");
}
}
Voyons comment le configurer dans le descripteur de déploiement, puis nous comprendrons sa mise en œuvre et son fonctionnement.
<?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>
Comme vous pouvez le voir, il est très facile de spécifier des servlets gestionnaires d’exceptions pour l’application en utilisant l’élément error-page. Chaque élément error-page doit avoir soit l’élément error-code soit l’élément exception-type. Nous définissons le servlet gestionnaire d’exceptions dans l’élément location. En fonction de cette configuration, si l’application génère une erreur 404 ou une ServletException, elle sera gérée par le servlet AppExceptionHandler. Lorsqu’une telle exception ou un tel scénario d’erreur se produit, le conteneur servlet invoquera la méthode HTTP correspondante du servlet de gestion des exceptions et transmettra l’objet de demande et de réponse. Notez que j’ai fourni la mise en œuvre des méthodes doGet() et doPost() afin qu’elle puisse gérer les requêtes GET et POST et utiliser une méthode commune pour les traiter. Avant que le conteneur servlet n’invite le servlet à gérer l’exception, il définit certains attributs dans la demande pour obtenir des informations utiles sur l’exception, dont certains sont javax.servlet.error.exception, javax.servlet.error.status_code, javax.servlet.error.servlet_name et javax.servlet.error.request_uri. Pour une exception, le code d’état est toujours 500, ce qui correspond à l' »Erreur de serveur interne ». Pour les autres types d’erreurs, nous obtenons différents codes d’erreur tels que 404, 403, etc. En utilisant le code d’état, notre mise en œuvre présente différents types de réponse HTML à l’utilisateur. Il fournit également un hyperlien vers la page d’accueil de l’application. Maintenant, lorsque nous accéderons à notre servlet qui génère une ServletException, nous obtiendrons une réponse comme l’image ci-dessous. Si nous essayons d’accéder à une URL invalide qui entraînera une réponse 404, nous obtiendrons une réponse comme l’image ci-dessous.
N’est-ce pas agréable et cela aide-t-il l’utilisateur à comprendre facilement ce qui s’est passé et leur fournit-il un moyen d’aller à l’endroit correct ? Cela évite également d’envoyer des informations sensibles sur l’application à l’utilisateur. Nous devrions toujours avoir des gestionnaires d’exceptions en place pour notre application Web. Si vous souhaitez gérer les exceptions d’exécution et toutes les autres exceptions dans un seul gestionnaire d’exceptions, vous pouvez spécifier exception-type comme Throwable.
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/AppExceptionHandler</location>
</error-page>
Si plusieurs entrées de page d’erreur existent, disons une pour Throwable et une pour IOException et que l’application lance FileNotFoundException, alors elle sera gérée par le gestionnaire d’erreur de IOException. Vous pouvez également utiliser une page JSP comme gestionnaire d’exception, il suffit de fournir l’emplacement du fichier jsp plutôt que le mappage de servlet. C’est tout pour la gestion des exceptions de servlet dans une application Web, j’espère que vous avez aimé.
Télécharger le projet d’exemple de gestion des exceptions de servlet
Consultez d’autres articles de cette série: