我使用tomcat 6的彗星将数据推送到客户端。
我希望在连接关闭之前接收数据(对于XMLHttpRequest,就绪状态= 3),问题是tomcat 6在发送之前缓冲数据,因此我需要做出棘手的事情来实现这一点。
我已将application / x-javascript和req内容类型的请求内容类型设置为application / xml(以禁用浏览器缓存)。
我在tomcat 6中使用了很多可用的选项来禁用缓存(nio连接器中的socketBuffer = -1等等),这在我的本地tomcat 6(在windows os上)上工作(实际上,即使没有修改任何默认选项。)
但是,具有相同tomcat 6配置的事件,当我在http://jelastic.com提供的tomcat 6服务器上部署应用程序时,服务器输出缓冲区很大,我不得不发送空字节来触发输出写入器冲洗(参见下面的代码)
byte [] bytes = new byte [event.getHttpServletResponse()。getBufferSize() - new Gson()。toJson(messagesContent).getBytes()。length]; event.getHttpServletResponse()。getOutputStream()。write(new Gson()。toJson(messagesContent).getBytes()); 。event.getHttpServletResponse()的getOutputStream()写(字节)。 。event.getHttpServletResponse()的getOutputStream()平齐();
如果除了数据内容之外我不写字节,数据也不会发送到客户端。这真的很烦人,因为我发送无用的空字节,因为我必须在客户端上管理这些空字节。可怕。
有没有人有解决方案?如何禁用comet servlet输出缓冲区。对我来说似乎很明显,默认情况下应该为彗星servlet禁用输出缓冲区。听起来很奇怪。
先谢谢,
Ĵ
答案 0 :(得分:3)
您是否尝试使用过滤器? 编程自定义请求和响应中的http://www.oracle.com/technetwork/java/filters-137243.html
使用装饰器模式可以控制输出。 这样做的方法是将生成响应的servlet传递给一个替代流。替代流可防止servlet在完成时关闭原始响应流。
class CharResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
public String toString() {
return output.toString();
}
public ResponseWrapper(HttpServletResponse response) {
super(response);
output = new CharArrayWriter();
}
public PrintWriter getWriter(){
return new PrintWriter(output);
}
}
所以在过滤器的doFilter方法中你得到原始的PrintWritter,传递包装器
PrintWriter out = response.getWriter();
CharResponseWrapper wrapper = new CharResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, wrapper);
然后Servlet将写入CharrArrayWritter中的所有输出,这样您就可以在不缓冲的情况下获取字符串中的输出
wrapper.toString()
然后您可以修改,追加..等,然后使用原始响应输出来写入内容。
out.write(wrapper.toString());
out.close();