Hogyan kezeljük az alkalmazásban azokat a kivételeket, amelyeket egy másik servlet dobott?
sobes.tech MI
Válasz az MI-től
A szabványos servlet architektúrában az egy servlet által dobott kivételek nem kezelhetők közvetlenül egy másik servlet által a jelenlegi kérés keretében. Minden kérés külön szálon kerül feldolgozásra, amely egy adott servlet életciklusához kapcsolódik.
Azonban elérhető hasonló viselkedés a következő megközelítésekkel:
-
A servlet konténer hibakezelő mechanizmusának használata:
- A
web.xml-ben konfigurálhatók hibák oldalak bizonyos kivételtípusokra vagy HTTP státuszkódokra. A servlet konténer (pl. Tomcat, Jetty) átirányít erre az oldalra kivétel esetén. - A hibás oldal (amely lehet más servlet vagy JSP) hozzáférhet a kérés attribútumaihoz az exception információkhoz.
- Az attribútumokat a
request.getAttribute()segítségével érhetjük el. Kulcsok például:javax.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>Hiba!</h2>"); out.println("<p>Státuszkód: " + statusCode + "</p>"); out.println("<p>Servlet: " + (servletName != null ? servletName : "Ismeretlen") + "</p>"); out.println("<p>Kérés URI: " + (requestUri != null ? requestUri : "Ismeretlen") + "</p>"); if (throwable != null) { out.println("<p>Kivétel típusa: " + throwable.getClass().getName() + "</p>"); out.println("<p>Üzenet: " + throwable.getMessage() + "</p>"); // Stack trace kiírása hibakereséshez // throwable.printStackTrace(out); } out.println("</body></html>"); } } - A
-
Servlet szűrők használata:
- Egy szűrő becsomagolhatja a
doFilterláncot egytry-catchblokkba. - Ha a láncban a servlet kivételt dob, a szűrő elkapja azt.
- A
catchblokkban a szűrő vagy saját maga kezeli a kivételt, vagy átirányítja a kérést egy speciális hibakezelőhöz (pl. más servlethez) arequest.getRequestDispatcher("/errorServlet").forward(request, response)segítségével.
// 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("/*") // A szűrő minden kérésre alkalmazva public class ExceptionHandlingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // Szűrő inicializálása } @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); // A kérés továbbítása a láncban (servlet vagy következő szűrő) } catch (Exception e) { // Kivétel elkapása, amit a servlet vagy a következő szűrő dobott System.err.println("Hiba történt a kérés feldolgozása során: " + httpRequest.getRequestURI()); e.printStackTrace(); // Hibák naplózása // Információk mentése a hibakezelő számára httpRequest.setAttribute("javax.servlet.error.exception", e); httpRequest.setAttribute("javax.servlet.error.message", e.getMessage()); httpRequest.setAttribute("javax.servlet.error.request_uri", httpRequest.getRequestURI()); // Státuszkód beállítása, ha ismert httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 belső szerverhiba // Átirányítás a hibakezelő servlethez httpRequest.getRequestDispatcher("/errorServlet").forward(httpRequest, httpResponse); } } @Override public void destroy() { // Erőforrások felszabadítása } } - Egy szűrő becsomagolhatja a
Ezek a megközelítések lehetővé teszik a hibák központosított kezelését és megakadályozzák, hogy a konténer alapértelmezett hibajelzései jelenjenek meg a felhasználónak. Az első módszer (a web.xml-en keresztül) egyszerűbb az alapvető státuszkód és kivételtípus kezeléséhez. A második módszer (a szűrőn keresztül) nagyobb rugalmasságot biztosít, lehetővé téve további logika végrehajtását (pl. naplózás) az átirányítás vagy kezelés előtt.