Como tratar na aplicação as exceções que foram lançadas por outro servlet?
sobes.tech IA
Resposta da IA
Na arquitetura padrão de servlets, as exceções lançadas por um servlet não podem ser tratadas diretamente por outro servlet na mesma requisição. Cada requisição é processada numa thread separada associada ao ciclo de vida de um servlet.
No entanto, é possível alcançar um comportamento semelhante usando as seguintes abordagens:
-
Utilização do mecanismo de tratamento de erros do contêiner de servlets:
- No
web.xml, pode-se configurar páginas de erro para tipos específicos de exceções ou códigos de estado HTTP. O contêiner de servlets (por exemplo, Tomcat, Jetty) redirecionará para essa página quando ocorrer uma exceção. - Na página de erro (que pode ser outro servlet ou JSP), pode-se obter informações sobre a exceção a partir dos atributos da requisição.
- Os atributos estão disponíveis através de
request.getAttribute(). As chaves incluemjavax.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>Erro!</h2>"); out.println("<p>Código de estado: " + statusCode + "</p>"); out.println("<p>Servlet: " + (servletName != null ? servletName : "Desconhecido") + "</p>"); out.println("<p>URI da requisição: " + (requestUri != null ? requestUri : "Desconhecido") + "</p>"); if (throwable != null) { out.println("<p>Tipo de exceção: " + throwable.getClass().getName() + "</p>"); out.println("<p>Mensagem: " + throwable.getMessage() + "</p>"); // Também é possível exibir a stack trace para depuração // throwable.printStackTrace(out); } out.println("</body></html>"); } } - No
-
Utilização de filtros de servlets:
- Um filtro pode envolver a cadeia
doFilterem um blocotry-catch. - Se um servlet na cadeia lançar uma exceção, o filtro a interceptará.
- Dentro do bloco
catch, o filtro pode tratar a exceção por si mesmo ou redirecionar a requisição para um manipulador de erros especial (possivelmente outro servlet) usandorequest.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("/*") // O filtro é aplicado a todas as requisições public class ExceptionHandlingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // Inicialização do filtro } @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); // Passa a requisição para o próximo na cadeia (servlet ou filtro) } catch (Exception e) { // Captura a exceção lançada pelo servlet ou filtro seguinte System.err.println("Ocorreu um erro ao processar a requisição para a URI: " + httpRequest.getRequestURI()); e.printStackTrace(); // Registro do erro // Salvando informações do erro para o manipulador httpRequest.setAttribute("javax.servlet.error.exception", e); httpRequest.setAttribute("javax.servlet.error.message", e.getMessage()); httpRequest.setAttribute("javax.servlet.error.request_uri", httpRequest.getRequestURI()); // Pode-se definir um código de status se conhecido httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 Internal Server Error // Redirecionando para o servlet de tratamento de erros httpRequest.getRequestDispatcher("/errorServlet").forward(httpRequest, httpResponse); } } @Override public void destroy() { // Limpeza de recursos do filtro } } - Um filtro pode envolver a cadeia
Essas duas abordagens permitem centralizar o tratamento de erros e evitar mostrar mensagens padrão de erro do contêiner ao usuário. A primeira forma (via web.xml) é mais simples para tratamento básico de códigos de estado e tipos de exceções. A segunda forma (via filtro) oferece maior flexibilidade, permitindo executar lógica adicional (por exemplo, registro) antes de redirecionar ou tratar.