2010-09-01 23 views
9

Tôi đã là ErrorFilter kéo dài mùa xuân GenericFilterBean. Tôi muốn hiển thị một trang lỗi được trang trí bằng các ô nếu một số lỗi xảy ra.Đặt tên chế độ xem trong bộ lọc lò xo

Có cách nào để đặt tên chế độ xem từ bộ lọc không?

<filter> 
    <filter-name>errorFilter</filter-name> 
    <filter-class>com.abc.filter.ErrorFilter</filter-class> 
    <init-param> 
     <param-name>errorPage</param-name> 
     <param-value>/jsp/errorpage.jsp</param-value> 
    </init-param> 
</filter> 

Đây là cấu hình trong web.xmldoFilter phương pháp trong errorfilter như sau:

public void doFilter(ServletRequest req, ServletResponse resp, 
     FilterChain chain) throws IOException, ServletException { 

    HttpServletRequest httpReq = (HttpServletRequest) req; 
    StringBuffer reqUrl = httpReq.getRequestURL(); 
    try { 
     chain.doFilter(req, resp); 
    } catch (Exception ex) { 
     String requestRepresentation = createRequestRepresentation(req); 
     errorService.handleException(reqUrl.toString(), ex, requestRepresentation); 
     req.getRequestDispatcher(
       getFilterConfig().getInitParameter("errorPage")).forward(req, resp); 
    } catch (Error er) { 
     errorService.handleError(reqUrl.toString(), er); 
     req.getRequestDispatcher(
       getFilterConfig().getInitParameter("errorPage")).forward(req, resp); 
    } 
} 

Các errorpage hiện tại không được trang trí bằng gạch, vì vậy tôi muốn để trang trí nó với bình thường đầu trang và chân trang và gọi tên chế độ xem đó từ bộ lọc.

Có thể không?

Edit: Về cơ bản chúng tôi muốn để có thể làm điều gì đó tương tự đến controller-phương pháp ví dụ trở lại "tên view";

Đã thử:

  • httpResponse.sendRedirect ("errorPageView"); không hoạt động, nó chuyển hướng đến http://server/fooerrorPageView
  • request.getRequestDispatcher ("errorPageView"). Forward (request, response); cũng không tương tự như trên (không có chuyển hướng http, nhưng cho cùng nội dung "không có lỗi trang")

Trả lời

0

Phải có cách để làm điều đó với Spring MVC, nhưng tôi cho rằng chuyển hướng là đủ.

try { 
    chain.doFilter(req, resp); 
} catch (Exception ex) { 
    if (response.isCommitted()) { 
     log(ex); // at least a part of the response is already sent to the client, you can't do much about it 
    } else { 
     session.setAttribute("last.exception", ex); 
     response.sendRedirect(request.getContextPath() + getFilterConfig().getInitParameter("errorPage")); 
    } 
} 

P.S. không bắt gặp lỗi!

+0

_sendRedirect_ sẽ chuyển hướng trình duyệt của khách hàng đến URL được chỉ định, bỏ qua bất kỳ độ phân giải tên chế độ xem nào. –

1

tôi nghĩ điều này là không thể, vì đây là bộ lọc servlet, sẽ được áp dụng sau khi servlet bản đồ yêu cầu lò xo được áp dụng. về cơ bản, servlet bản đồ yêu cầu cho rằng nó đã hoàn thành và chuyển yêu cầu trở lại thùng chứa servlet.

tên chế độ xem chỉ hoạt động INSIDE của mùa xuân - ngoài mùa xuân, trong thùng chứa servlet, bạn sẽ phải nói về url, chứ không phải xem tên.

chuyển hướng đến url cụ thể sẽ hoạt động. cho điều này, bạn phải nhận thức được sự khác biệt giữa chuyển hướng và chuyển tiếp.

một chuyển hướng gửi tiêu đề sau đây cho khách hàng:

Location: http://server/new/location

cùng với mã trạng thái 301 (chuyển hướng vĩnh viễn, để cho khách hàng biết rằng nó có thể cache thông tin này) hoặc 307 (chuyển hướng tạm thời, để thông báo cho khách hàng rằng họ sẽ hỏi lại lần sau, bởi vì chuyển hướng có thể thay đổi)

chuyển tiếp yêu cầu về cơ bản bắt chước yêu cầu mới và bạn có thể gửi yêu cầu tới bất kỳ servlet nào trong cùng một vùng chứa. điều này có nghĩa, bạn phải C takeNG xem xét đường dẫn ngữ cảnh, có nghĩa là câu trả lời @iimuhin đã cho:

response.sendRedirect(
     request.getContextPath() + 
     getFilterConfig().getInitParameter("errorPage")); 

thực sự là đúng cách để đi. bạn có thể (nên) thêm ghi nhật ký để xem điều gì thực sự xảy ra và đường dẫn nào thực sự được sử dụng.

cũng - bạn phải biết về bộ đệm. một phản hồi servlet thường được đệm, và không có gì được gửi đến máy khách cho đến khi bộ đệm đầy hoặc toàn bộ quá trình xử lý đã kết thúc.

khi nó bị xóa, tiêu đề được viết trước. điều này có nghĩa là việc thay đổi các tiêu đề SAU KHI câu trả lời đã bị xóa là không thể, bởi vì chúng đã được gửi đi.

đây là lý do tại sao servlet có thể buộc xả nước, nhưng thường không nên.

trong trường hợp của bạn, bạn có thể muốn tăng kích thước bộ đệm trên phản ứng:

response.setBufferSize(int size) 

trước khi gọi chain.doFilter() để tránh xả sớm.

+0

Cảm ơn bạn rất nhiều vì đã giải thích chi tiết về vấn đề này. +1 để đề cập đến sự khác biệt giữa chuyển hướng và chuyển tiếp. – yuva

1

Tại sao bạn không sử dụng cơ chế xử lý lỗi của mùa xuân? ở đây bài đăng tốt về nó (với các ví dụ) - https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

Ngoài ra, không chắc chắn nếu có cách làm sạch sẽ. Các đề xuất khác có thể thực hiện cuộc gọi đến ứng dụng của bạn để nhận phản hồi trang lỗi và đầu ra phản hồi thay thế (trong trường hợp đó, bạn cũng sẽ cần phải sử dụng phản hồi http "đệm" để đảm bảo luồng chưa được xóa) hoặc tạo chuyển hướng đến url lỗi.

+0

Đề xuất của bạn hoạt động nếu người hỏi muốn hiển thị trang lỗi từ bộ điều khiển. Những gì anh ta muốn là xây dựng một trang lỗi từ bên trong Bộ lọc Servlet trước khi yêu cầu chuyển đến bộ điều khiển. Vì vậy, Xử lý ngoại lệ không thể hoạt động ở đây. Đề xuất thứ hai của bạn đáng lưu ý. – yuva

+1

cảm ơn bạn đã trả lời và đánh giá của bạn, nhưng tại sao bạn nghĩ rằng bộ lọc servlet không thể bắt ngoại lệ được ném trong bộ điều khiển lò xo hoặc sau khi thực hiện điều khiển lò xo (nói cách khác về cách quay lại sau khi thực hiện bộ điều khiển)? – Maks

+0

toàn bộ câu trả lời của tôi là: - sử dụng chức năng sring nếu bạn có thể - nếu bạn (vì lý do gì) không thể sử dụng, chuyển hướng hoặc phân tích cú pháp phản hồi (trong bộ lọc) vẫn là một tùy chọn. Nhưng điều đó có thể chỉ hoạt động nếu phản ứng chưa được cam kết. Có hợp lý không? – Maks

1

Bộ lọc xuất hiện trước mùa xuân. Đậu mùa xuân có thể được tiêm trong Bộ lọc bằng cách sử dụng cơ chế ApplicationContextAware, nhưng tạo thành một khung nhìn Spring MVC có nghĩa là bạn sẽ phải giữ toàn bộ khung công tác MVC mùa xuân trong Bộ lọc của bạn. Tôi nghĩ rằng điều này là không thể và bạn sẽ phải chuyển tiếp yêu cầu bằng cách sử dụng RequestDispatcher không đến một khung nhìn mùa xuân nhưng để xem tùy chỉnh của riêng bạn.

0

Chỉ cần kiểm tra url chuyển hướng của bạn. bạn có thể truy cập trang bằng url.

public void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url) 
     throws IOException { 
    String redirectUrl = request.getContextPath() + url; 
    redirectUrl = response.encodeRedirectURL(redirectUrl); 

    if (logger.isDebugEnabled()) { 
     logger.debug("Redirecting to '" + redirectUrl + "'"); 
    } 

    response.sendRedirect(redirectUrl); 
}