Cum să gestionezi în aplicație excepțiile care au fost aruncate de un alt servlet?
sobes.tech AI
Răspuns de la AI
În arhitectura standard a servlets, excepțiile aruncate de un servlet nu pot fi gestionate direct de către alt servlet în cadrul aceleiași cereri. Fiecare cerere este procesată de un thread separat, asociat cu ciclul de viață al unui singur servlet.
Cu toate acestea, se poate realiza un comportament similar utilizând următoarele abordări:
-
Utilizarea mecanismului de gestionare a erorilor al containerului de servlets:
- În
web.xmlse pot configura pagini de eroare pentru anumite tipuri de excepții sau coduri de stare HTTP. Containerul de servlets (de exemplu, Tomcat, Jetty) va redirecționa către această pagină în cazul unei excepții. - Pe pagina de eroare (care poate fi un alt servlet sau JSP) se poate obține informație despre excepție din atributele cererii.
- Atributele sunt accesibile prin
request.getAttribute(). Cheile includjavax.servlet.error.exception,javax.servlet.error.exception_type,javax.servlet.error.message,javax.servlet.error.request_uri.
<error-page> <exception-type>java.lang.RuntimeException</exception-type> <location>/errorServlet</location> </error-page> <error-page> <error-code>500</error-code> <location>/errorServlet</location> </error-page>// ErrorServlet.java import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet("/errorServlet") public class ErrorServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 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"); String requestUri = (String) request.getAttribute("javax.servlet.error.request_uri"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><body>"); out.println("<h2>Eroare!</h2>"); out.println("<p>Cod stare: " + statusCode + "</p>"); out.println("<p>Servlet: " + (servletName != null ? servletName : "Necunoscut") + "</p>"); out.println("<p>URI cerere: " + (requestUri != null ? requestUri : "Necunoscut") + "</p>"); if (throwable != null) { out.println("<p>Tip excepție: " + throwable.getClass().getName() + "</p>"); out.println("<p>Mesaj: " + throwable.getMessage() + "</p>"); // Se poate afișa și stack trace pentru depanare // throwable.printStackTrace(out); } out.println("</body></html>"); } } - În
-
Utilizarea filtrelor de servlets:
- Un filtru poate înveli lanțul
doFilterîntr-un bloctry-catch. - Dacă un servlet din lanț aruncă o excepție, filtrul o va captura.
- În blocul
catch, filtrul poate fie să gestioneze excepția singur, fie să redirecționeze cererea către un handler de erori special (posibil alt servlet) folosindrequest.getRequestDispatcher("/errorServlet").forward(request, response).
// ExceptionHandlingFilter.java import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter("/*") // Filtru aplicat tuturor cererilor public class ExceptionHandlingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // Inițializare filtru } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; try { chain.doFilter(request, response); // Trimiterea cererii mai departe în lanț (la servlet sau alt filtru) } catch (Exception e) { // Capturarea excepției aruncate de servlet sau alt filtru System.err.println("A apărut o eroare în procesarea cererii pentru URI: " + httpRequest.getRequestURI()); e.printStackTrace(); // Logare eroare // Salvarea informației despre eroare pentru handler httpRequest.setAttribute("javax.servlet.error.exception", e); httpRequest.setAttribute("javax.servlet.error.message", e.getMessage()); httpRequest.setAttribute("javax.servlet.error.request_uri", httpRequest.getRequestURI()); // Se poate seta codul de stare, dacă este cunoscut httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 Internal Server Error // Redirecționare către servlet-ul de gestionare a erorilor httpRequest.getRequestDispatcher("/errorServlet").forward(httpRequest, httpResponse); } } @Override public void destroy() { // Curățarea resurselor filtrului } } - Un filtru poate înveli lanțul
Această abordare permite centralizarea gestionării erorilor și evitarea afișării mesajelor standard de eroare ale containerului utilizatorului. Prima metodă (prin web.xml) este mai simplă pentru gestionarea de bază a codurilor de stare și tipurilor de excepții. A doua metodă (prin filtru) oferă mai multă flexibilitate, permițând executarea de logică suplimentară (de exemplu, logare) înainte de redirecționare sau gestionare.