2012-11-20 36 views
6

Tôi tự hỏi nếu tôi có thể sử dụng một bộ lọc (trong trường hợp của tôi một CorsFilter) để đo thời gian VÀ để đặt thời gian đưa vào tin nhắn chính nó. Tôi biết rằng các công trình sau đây ok:Làm cách nào để sử dụng bộ lọc để đo lường hiệu suất?

public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { 
    long startTime = System.nanoTime(); 
    chain.doFilter(request, response); 
    long endTime = System.nanoTime(); 
    System.out.println("Time: " + (endTime - startTime)); 
} 

Tất nhiên kết quả là tổng thời gian tính bằng giây. Tôi muốn đặt thời gian vào tiêu đề của phản hồi trả về để người nhận có thể xem tiêu đề và xem thời gian xử lý mất bao lâu. Mã sau đây không hoạt động:

public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { 
    long startTime = System.nanoTime(); 
    if(response instanceof HttpServletResponse) { 
    HttpServletResponse httpResp = (HttpServletResponse)response; 
    httpResp.addHeader("Start-time", Long.toString(startTime)); 
    } 

    chain.doFilter(request, response); 
    long endTime = System.nanoTime(); 
    if(response instanceof HttpServletResponse) { 
    HttpServletResponse httpResp = (HttpServletResponse)response; 
    httpResp.addHeader("End-time", Long.toString(endTime)); 
    } 
} 

Tiêu đề chỉ bao gồm thời gian bắt đầu và không kết thúc. Tôi giả định rằng điều này là do tin nhắn đã được gửi để sửa đổi đối tượng sẽ không có hiệu lực.

Có ai có giải pháp thanh lịch/thông minh để đặt thời gian vào tiêu đề thông qua việc sử dụng bộ lọc không?

Cảm ơn, Phil

Cập nhật

Tôi đã điều tra việc sử dụng một HttpServletResponseWrapper để giải quyết giải pháp này. Điều này vẫn không thể xuất ra XXX-EndTime hoặc YYY-EndTime trên tiêu đề phản hồi.

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

    if(response instanceof HttpServletResponse) { 
    HttpServletResponse httpResp = (HttpServletResponse)response; 
    httpResp.addHeader("Access-Control-Allow-Origin", "*"); 
    httpResp.addHeader("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS"); 
    httpResp.addHeader("Allow", "GET, HEAD, OPTIONS"); 
    httpResp.addHeader("Access-Control-Allow-Headers", "*"); 
    httpResp.addHeader("A-Runtime", Long.toString(startTime)); 
    } 

    OutputStream out = response.getOutputStream(); 

    GenericResponseWrapper wrapper = new GenericResponseWrapper((HttpServletResponse) response); 

    chain.doFilter(request,wrapper); 

    out.write(wrapper.getData()); 

    if(response instanceof HttpServletResponse) { 
HttpServletResponse httpResp = (HttpServletResponse)response; 
httpResp.addHeader("XXX-EndTime", Long.toString(System.nanoTime() - startTime)); 

    wrapper.addHeader("YYY-EndTime", Long.toString(System.nanoTime() - startTime)); 
    } 

    out.close(); 
} 

Trả lời

2

Hãy xem HttpServletResponseWrapper.


Được rồi, sau đó mã:

Mã này đệm đầu ra (trong hai thời trang) để thêm các tiêu đề sau khi công trình pseudo-đầu ra. Trên thực tế addHeader có thể đã được thực hiện bằng cách xuất, vì vậy chúng tôi là may mắn nó hoạt động. Mã trường hợp đường viền. Nếu không may mắn, addHeader sẽ phải được overriden.

Tâm trí, khi tôi thử, chỉ getOutputStream được gọi trong ứng dụng thử nghiệm của tôi. Có một sự lựa chọn để được thực hiện hoặc chọn getPrintWriter hoặc getOutputStream.

private static class PostponingResponseWrapper extends HttpServletResponseWrapper { 

    private ByteArrayOutputStream bos; 
    private ServletOutputStream outputStream; 
    private StringWriter sw; 
    private PrintWriter printWriter; 
    private boolean usingOutputStream; 
    private boolean usingWriter; 

    public PostponingResponseWrapper (HttpServletResponse response) { 
     super(response); 
     bos = new ByteArrayOutputStream(); 
     outputStream = new ServletOutputStream() { 
      @Override 
      public void write(int b) throws IOException { 
       bos.write(b); 
      } 
     }; 
     sw = new StringWriter(); 
     printWriter = new PrintWriter(sw); 
    } 

    @Override 
    public PrintWriter getWriter() throws IOException { 
     usingWriter = true; 
     LOGGER.info("getWriter usingWriter {}, usingOutputStream {}", usingWriter, usingOutputStream); 
     return printWriter; 
    } 

    @Override 
    public void flushBuffer() throws IOException { 
     LOGGER.info("flushBuffer"); 
    } 

    @Override 
    public ServletOutputStream getOutputStream() throws IOException { 
     usingOutputStream = true; 
     LOGGER.info("getOutputStream usingWriter {}, usingOutputStream {}", usingWriter, usingOutputStream); 
     ServletOutputStream out = new ServletOutputStream() { 
      @Override 
      public void write(int b) throws IOException { 
       outputStream.write(b); 
      } 
     }; 
     return out; 
    } 

    public void finish() throws IOException { 
     LOGGER.info("finish"); 
     if (usingWriter) { 
      super.getWriter().print(sw.toString()); 
     } else if (usingOutputStream) { 
      super.getOutputStream().write(bos.toByteArray()); 
     } 
    } 
} 

public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 
    HttpServletResponse httpServletResponse = (HttpServletResponse) response; 
    PostponingResponseWrapper responseWrapper = 
      new PostponingResponseWrapper (httpServletResponse); 
    responseWrapper.addHeader("Before", "Already-Worked"); 
    chain.doFilter(request, responseWrapper); 
    responseWrapper.addHeader("After", "And-Now-This"); 
    responseWrapper.finish(); // Writes the actual response 
} 
+2

-1 câu trả lời thích điều này sẽ mở ra nhiều câu hỏi hơn sau đó họ trả lời. – Yevgeniy

+0

@YevgeniyM. bạn đúng, chỉ cần có một bình luận, rằng có một lớp bao bọc như vậy +1. –

+0

Ok, tôi đã thực hiện một giải pháp bằng cách sử dụng HttpServletResponseWrapper nhưng vẫn không thể làm cho nó hoạt động! Tôi sẽ cập nhật câu hỏi ở trên bằng mã mới của mình. – Phil

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