2015-05-20 10 views
5

Chúng tôi hiện đang làm việc để thêm tiêu đề cho mỗi phản hồi từ ứng dụng của chúng tôi. Để thêm các tiêu đề này, chúng tôi đang sử dụng API Servlet Filter -interface.Bộ lọc Java Servlet: Tôi phải thêm tiêu đề trước khi chuyển đến chuỗi, tài liệu hướng dẫn cách khác

Chúng tôi đã có các bộ lọc sau đây trong ứng dụng của chúng tôi:

public class SecurityFilter implements Filter 
{ 
    @Override 
    public void init(FilterConfig filterConfig) throws ServletException 
    { 

    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
    { 
     chain.doFilter(request, response); 

     HttpServletResponse httpServletResponse = ((HttpServletResponse) response); 
     httpServletResponse.addHeader("X-Frame-Options", "DENY"); 
     httpServletResponse.addHeader("X-Content-Type-Options", "nosniff"); 
    } 

    @Override 
    public void destroy() 
    { 

    } 
} 

này (đặc biệt là doFilter -method) được triển khai đúng theo tài liệu hướng dẫn, điều này cho thấy trình tự sau công việc:

  1. Kiểm tra yêu cầu
  2. Tùy chọn bọc đối tượng yêu cầu với triển khai tùy chỉnh để lọc nội dung hoặc tiêu đề cho đầu vào f iltering
  3. tùy ý quấn đối tượng phản ứng với một thực hiện tùy chỉnh để lọc nội dung hoặc tiêu đề để lọc ra

    • Hoặc gọi đơn vị tiếp theo trong chuỗi bằng cách sử dụng đối tượng FilterChain (chain.doFilter()),
    • hoặc không vượt qua trên cặp request/response để đơn vị tiếp theo trong chuỗi bộ lọc để chặn quá trình xử lý yêu cầu
  4. tiêu đề trực tiếp thiết lập trên các phản ứng sau khi gọi của đối tượng tiếp theo trong chuỗi bộ lọc.

Theo như chúng ta có thể thấy, thứ tự của doFilter -method của chúng tôi là đúng theo tài liệu hướng dẫn (vượt qua yêu cầu đến chuỗi đầu tiên như đã nêu dưới điểm 4, thêm tiêu đề tùy chỉnh sau đó như đã nêu dưới điểm 5). Tuy nhiên, tiêu đề chúng tôi thêm không hiển thị trong câu trả lời. Nếu chúng tôi thay đổi theo thứ tự như sau, mọi thứ có vẻ hoạt động tốt:

@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
{ 
    HttpServletResponse httpServletResponse = ((HttpServletResponse) response); 
    httpServletResponse.addHeader("X-Frame-Options", "DENY"); 
    httpServletResponse.addHeader("X-Content-Type-Options", "nosniff"); 

    chain.doFilter(request, response); 
} 

Có ai giải thích được hành vi này không?

+0

Có bất kỳ bộ lọc nào khác? –

+0

@EvanKnowles có. Tôi nghĩ rằng đó là một phần của vấn đề, như Nikos Paraskevopoulos chỉ ra bên dưới một bộ lọc khác rất có thể cam kết yêu cầu. –

Trả lời

2

Tôi không biết những gì phiên bản của spec Servlet bạn đang đề cập đến, nhưng trong 3.1, chương 6.2.1 "Lọc Vòng đời" Tôi đọc (tôi nhấn mạnh):

  1. Sau khi gọi bộ lọc tiếp theo trong chuỗi, bộ lọc có thể kiểm tra các tiêu đề phản hồi.

"Kiểm tra" không "đặt"! Trên thực tế, thông số kỹ thuật cho các phương thức tiêu đề cho biết (Servlet 3.1, chương 5.2 "Tiêu đề"):

Để được truyền lại thành công cho khách hàng, phải đặt tiêu đề trước khi phản hồi được thực hiện. Các tiêu đề được đặt sau khi phản hồi được cam kết sẽ bị bỏ qua bởi thùng chứa servlet.

Tôi đoán điều này đang xảy ra với yêu cầu của bạn, một số servlet hoặc lọc chuỗi là "cam kết", vì vậy các tiêu đề bị bỏ qua.

Dòng dưới cùng: Thông số kỹ thuật (ít nhất là như tôi thấy trong 3.1) không suugest để đặt tiêu đề sau khi gọi chain.doFilter(). Phiên bản thứ hai của bạn hoạt động chính xác (và cách tôi luôn triển khai các bộ lọc bổ sung tiêu đề)!

+0

Cảm ơn bạn đã trả lời. Tôi vừa cam kết thay đổi sau khi chúng tôi đã đọc tài liệu cho spec 3.0 tài liệu giống như bạn đã trích dẫn. Ngớ ngẩn cách nhận xét mã sử dụng mô tả khó hiểu cho phương thức 'doFilter' mặc dù ... –

3

Oracle cho bạn biết để bọc các phản ứng trước khi đi qua nó xuống chuỗi, nếu bạn muốn thêm một cái gì đó sau khi

Lưu ý rằng nếu bạn muốn xử lý trước các đối tượng yêu cầu hoặc postprocess đối tượng response, bạn không thể thao tác trực tiếp đối tượng yêu cầu hoặc đối tượng phản hồi gốc. Bạn phải sử dụng trình bao bọc. Khi xử lý sau một phản ứng, ví dụ, servlet mục tiêu đã hoàn thành và phản hồi có thể đã được cam kết trước khi bộ lọc có cơ hội làm bất kỳ điều gì với phản hồi. Bạn phải vượt qua trình bao trả lời thay vì phản hồi ban đầu trong chuỗi doFilter() gọi. Xem "Sử dụng bộ lọc để gói và thay đổi yêu cầu hoặc phản hồi".

http://docs.oracle.com/cd/B32110_01/web.1013/b28959/filters.htm#BCFCIHAH

Các vấn đề liên quan