როგორ უნდა მოიქცეს აპლიკაციაში სხვა სერვლეტით გადაყრილი გამონაკლისების შემთხვევაში?
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("მოთხოვნის დამუშავების დროს მოხდა შეცდომა: " + 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-ის საშუალებით) უფრო მარტივია ძირითადი სტატუს კოდებისა და გამონაკლისების ტიპების დამუშავებისთვის. მეორე მეთოდი (ფილტრის საშუალებით) უფრო მოქნილია, რადგან საშუალებას გაძლევთ დამატებითი ლოგიკა შეიტანოთ (მაგალითად, ლოგირება) და გადამისამართებამდე ან დამუშავების დროს.