Tətbiqdə başqa servlet tərəfindən atılan istisnaları necə idarə etmək olar?
sobes.tech Süni İntellekt
AI-dan cavab
Standart servlet memarlığında, bir servlet tərəfindən atılan istisnalar, cari sorğu çərçivəsində başqa bir servlet tərəfindən birbaşa işlənə bilməz. Hər bir sorğu ayrı bir thread-də işlənir və bu thread, bir servlet-in həyat dövrü ilə əlaqəlidir.
Ancaq, aşağıdakı yanaşmaları istifadə edərək oxşar davranış əldə etmək mümkündür:
-
Servlet konteynerinin xəta idarəetmə mexanizmi:
web.xmlfaylında müəyyən istisna növləri və ya HTTP vəziyyət kodları üçün xəta səhifələri konfiqurasiya edilə bilər. Servlet konteyneri (məsələn, Tomcat, Jetty) bu səhifəyə yönləndirəcək.- Xəta səhifəsində (başqa servlet və ya JSP ola bilər) sorğu atributlarından istisna haqqında məlumat əldə etmək olar.
- Atributlar
request.getAttribute()vasitəsilə mövcuddur. Açarlarjavax.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>Xəta!</h2>"); out.println("<p>Status kodu: " + statusCode + "</p>"); out.println("<p>Servlet: " + (servletName != null ? servletName : "Naməlum") + "</p>"); out.println("<p>Sorğu URI: " + (requestUri != null ? requestUri : "Naməlum") + "</p>"); if (throwable != null) { out.println("<p>Xəta tipi: " + throwable.getClass().getName() + "</p>"); out.println("<p>Mesaj: " + throwable.getMessage() + "</p>"); // Debug üçün stack trace göstərilə bilər // throwable.printStackTrace(out); } out.println("</body></html>"); } } -
Servlet filtrlərindən istifadə:
- Filtr
doFilterzəncirinitry-catchblokunda bükə bilər. - Əgər servlet zəncirində istisna atılırsa, filtr onu tutacaq.
catchblokunda filtr istisnayı özünə işləyə və ya sorğunu xüsusi xəta işləyicisinə (mümkün olan başqa servlet) yönləndirə bilər, məsələn,request.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("/*") // Bütün sorğulara tətbiq olunur public class ExceptionHandlingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // Filtrin başlanması } @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); // Sorğunu növbəti mərhələyə göndər } catch (Exception e) { // Servlet və ya növbəti filtr tərəfindən atılan istisnanı tutmaq System.err.println("Sorğunun işlənməsi zamanı xəta: " + httpRequest.getRequestURI()); e.printStackTrace(); // Xətanın qeydiyyatı // Xəta haqqında məlumatların saxlanması httpRequest.setAttribute("javax.servlet.error.exception", e); httpRequest.setAttribute("javax.servlet.error.message", e.getMessage()); httpRequest.setAttribute("javax.servlet.error.request_uri", httpRequest.getRequestURI()); // Status kodu təyin edilə bilər httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 Internal Server Error // Xəta işləyicisinə yönləndirmək httpRequest.getRequestDispatcher("/errorServlet").forward(httpRequest, httpResponse); } } @Override public void destroy() { // Filtr resurslarının təmizlənməsi } } - Filtr
Bu iki yanaşma xəta idarəetməsini mərkəzləşdirməyə və istifadəçiyə konteynerin standart xəta mesajlarının göstərilməsinin qarşısını almağa imkan verir. Birinci üsul (web.xml vasitəsilə) daha sadədir və əsas status kodlarının və istisna tiplərinin idarə olunmasına imkan verir. İkinci üsul (filtr vasitəsilə) daha çevikdir və əlavə loqlama və ya digər xüsusi işləmə imkanları təqdim edir.