2013-10-03 34 views
0

即使提交響應,是否可以將響應字節寫入HTTPServletResponse的OutputStream? 我有一個Servlet過濾器,通過調用doFilter將請求轉發給CXFServlet。在doFilter之後,我明確地想要在OutputStream中寫入字節。目前,我在響應提交後寫入OutputStream時沒有得到響應。提交HTTPServletResponse後寫入outputStream

public void doFilter(ServletRequest servletRequest, 
     ServletResponse servletResponse, FilterChain filterChain) 
     throws IOException, ServletException { 
    final HttpServletResponse response = (HttpServletResponse) servletResponse; 

    final ByteArrayPrintWriter pw = new ByteArrayPrintWriter(); 
    HttpServletResponse wrappedResp = new HttpServletResponseWrapper(
      response) { 
     public PrintWriter getWriter() { 
      return pw.getWriter(); 
     } 

     public ServletOutputStream getOutputStream() { 
      return pw.getStream(); 
     } 
    }; 
    filterChain.doFilter(servletRequest, wrappedResp); 

    byte[] bytes = pw.toByteArray(); 
    response.getOutputStream().write(bytes); 
    response.getOutputStream().flush(); 
    response.getOutputStream().close(); 

// Do logging after response is sent to client. 


} 
+0

您必須展示您的過濾器實現,因爲提交響應只是意味着狀態代碼和頭文件將被寫入。 –

+0

@SotiriosDelimanolis:我添加了我的過濾器實現。 – apurva

+0

所以你說客戶沒有迴應?你的日誌說什麼?你可以調試,以檢查「字節」實際上包含的東西? –

回答

0

我看到了兩個可能的問題:

1)如果您收到來自pwbyte[] bytes內容(把該行斷點),這意味着該過濾器和包裝做他們的工作和你的servlet(或其他內部過濾器)確實以某種方式關閉了真實的response。或者 - 嘗試使用Writer代替,我猜ByteArrayPrintWriter確實有一個返回char[]的方法,因此您可以使用response.getWriter()來編寫內容。

2)如果byte[] bytes中沒有內容,則ByteArrayPrintWriter不能正確收集內容。請注意,實現可能(或將)關閉響應編寫器,因此可能關閉ByteArrayPrintWriter的實現,這就是爲什麼您不能獲得任何內容。

您也可以嘗試以下方法:

BufferResponseWrapper wrappedResp = new BufferResponseWrapper(response); 
filterChain.doFilter(request, wrappedResp); 

// get buffered content 
char[] chars = wrapper.getBufferContentAsChars(); 
// modify it somehow 
chars = ArraysUtil.join(chars, "peep!".toCharArray()); 
// flush 
wrapper.writeContentToResponse(chars); 

Jodd項目:BufferResponseWrapper.java

編輯

這裏是類似的過濾器爲我工作在Tomcat上,只使用Java類:

public class MyFilter implements Filter { 

public void init(FilterConfig filterConfig) throws ServletException { 
} 

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 

    final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    final ByteArrayPrintWriter pw = new ByteArrayPrintWriter(baos); 

    HttpServletResponse wrappedResp = new HttpServletResponseWrapper((HttpServletResponse) servletResponse) { 
     @Override 
     public PrintWriter getWriter() { 
      return pw; 
     } 

     @Override 
     public ServletOutputStream getOutputStream() { 
      return new ServletOutputStream() { 
       @Override 
       public void write(int b) { 
        baos.write(b); 
       } 
      }; 
     } 
    }; 

    filterChain.doFilter(servletRequest, wrappedResp); 
    byte[] bytes = baos.toByteArray(); 
    servletResponse.getOutputStream().write(bytes); 
} 

public void destroy() { 
} 

public static class ByteArrayPrintWriter extends PrintWriter { 
    public ByteArrayPrintWriter(OutputStream out) { 
     super(out); 
    } 
} 
} 

請注意這是一個快速和骯髒實現,使用僅用於說明目的。