Ինչպե՞ս մշակել հավելվածում այն արտակարգ իրավիճակները, որոնք նետվել են այլ սերվլետով։
sobes.tech AI
Պատասխան AI-ից
Ստանդարտ սերվլետային ճարտարապետությունում, մեկ սերվլետով արտածված արտահայտությունները չեն կարող ուղղակիորեն մշակվել մյուս սերվլետով ընթացիկ հարցում։ Յուրաքանչյուր հարցում մշակվում է առանձին հոսքով, որը կապված է մեկ սերվլետի կյանքի ցիկլի հետ։
Այնուամենայնիվ, նման վարքագիծ հասնելու համար կարող եք օգտագործել հետևյալ մոտեցումները:
-
Սերվլետների կոնտեյների սխալի մշակման մեխանիզմի օգտագործում:
web.xml-ում կարող եք կարգավորել սխալի էջեր որոշակի արտահայտությունների կամ HTTP վիճակային կոդերի համար։ Սերվլետ կոնտեյները (օրինակ, Tomcat, Jetty) կուղղորդի այս էջը արտահայտության դեպքում։- Սխալի էջում (որը կարող է լինել այլ սերվլետ կամ JSP) կարող եք ստանալ արտահայտության մասին տեղեկատվություն հարցման ատրիբուտներից։
- Ատրիբուտները հասանելի են
request.getAttribute()-ով։ Կլուպները ներառում են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>Սխալ!</h2>"); out.println("<p>Կարգավիճակի կոդը: " + statusCode + "</p>"); out.println("<p>Սերվլետը: " + (servletName != null ? servletName : "Անհայտ") + "</p>"); out.println("<p>Հարցման URI: " + (requestUri != null ? requestUri : "Անհայտ") + "</p>"); if (throwable != null) { out.println("<p>Արտահայտության տեսակ: " + throwable.getClass().getName() + "</p>"); out.println("<p>Հաղորդագրություն: " + throwable.getMessage() + "</p>"); // Կարող եք նաև արտածել stack trace-ը դետալների համար // throwable.printStackTrace(out); } out.println("</body></html>"); } } -
Սերվլետների ֆիլտրերի օգտագործում:
- Ֆիլտրն կարող է շրջապատել
doFilterշղթանtry-catchբլոկով: - Եթե սերվլետը շղթայում արտածում է արտահայտություն, ֆիլտրն այն կփողվի:
catchբլոկում ֆիլտրն կարող է ինքնուրույն մշակել արտահայտությունը կամ ուղղորդել հարցումը հատուկ սխալի մշակողին (միգուցե այլ սերվլետ)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("/*") // Ֆիլտրն կիրառվում է բոլոր հարցումների վրա public class ExceptionHandlingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // Ֆիլտրի ինիցիալիզացիա } @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); // Հարցման փոխանցում շղթայում } catch (Exception e) { // Արտածված արտահայտության բռնում System.err.println("Սխալ է տեղի ունեցել հարցման մշակման ժամանակ URI: " + httpRequest.getRequestURI()); e.printStackTrace(); // Լոգավորում // Սխալի մասին տեղեկատվության պահպանում httpRequest.setAttribute("javax.servlet.error.exception", e); httpRequest.setAttribute("javax.servlet.error.message", e.getMessage()); httpRequest.setAttribute("javax.servlet.error.request_uri", httpRequest.getRequestURI()); // Կարող եք կարգավորել կարգավիճակի կոդը, եթե այն հայտնի է httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 Internal Server Error // Մղում սխալի մշակման սերվլետ httpRequest.getRequestDispatcher("/errorServlet").forward(httpRequest, httpResponse); } } @Override public void destroy() { // Ֆիլտրի ռեսուրսների մաքրում } } - Ֆիլտրն կարող է շրջապատել
Այս երկու մոտեցումները թույլ են տալիս կենտրոնականացնել սխալի մշակումը և կանխել ստանդարտ սխալի հաղորդագրությունների ցուցադրությունը։ Առաջին մեթոդը (web.xml-ով) ավելի պարզ է հիմնական սխալի կոդերի և արտահայտությունների տեսակների համար։ Երկրորդ մեթոդը (ֆիլտրով) ավելի ճկուն է, թույլ տալով ավելացնել լրացուցիչ լոգիկա (օրինակ, լոգավորում) նախքան ուղղորդումը կամ մշակումը։