我们知道在Java EE servlet / jsp中,客户端可以为一个http请求获取一个http响应。我想实现一些具有未知http响应长度的东西。我希望服务器在客户端发送第一个http请求后继续为客户端推送数据。在这种情况下,我不想使用AJAX,因为AJAX非常重要。
例如,我想创建一个可以从Web服务器检索日志消息的网页,当从另一个模块生成日志消息时,Web服务器可以发送日志消息(所以在这种情况下,时间间隔是未知,我们假设这里不是常规定时器检查)。日志消息附加到Web浏览器,这意味着Web浏览器无法刷新,例如:
记录中午12点..... 记录下午12:03 ..... 记录下午12:04 ..... 。 。
如何通过仅发送一个http请求并继续检索http响应来完成此操作?
@dystroy
你的意思是,我可以在doPost / doGet结束之前多次刷新printwriter(当有新的日志数据时)?
请忽略语法错误!我没有使用IDE。
protected void doPost(HttpServletRequest req, HttpServletResponse resp){
PrintWriter pw = resp.getWriter();
pw.println("<html><body>Testing for the streaming.</body></html>");
pw.flush();
/*
The syntax could not be correct, please focus on logic.
This while loop check the log sent by web server is finised or not and flush the data to the
client, after that the javascript will change the content of the inner Html. Is the logic below
valid?
*/
while(!log.finish()){
pw.println("document.setInnerHtml("+log.newLog()+")");
pw.flush();
}
}
答案 0 :(得分:0)
你总是可以使用长的http答案并定期刷新它,它起作用,至少在网络出现短暂问题之前。你不必在HTTP标题中发送答案的长度。
正确的解决方案要么使用ajax进行拉动,要么使用websockets,这些非常轻巧,但并非所有浏览器都支持(参见http://caniuse.com/websockets)。
关于“重量级”ajax,注意成本基本上是http查询+答案之一。如果你没有要求延迟小于100毫秒并且连接正常,你会发现ajax相当快(更喜欢使用servlet而不是jsp)。只是不要以太重的格式封装你的日志。
答案 1 :(得分:0)
当然,您需要考虑使用keep-alive
。
它允许客户端重用现有连接以连续从服务器读取数据。下面,只是从下面列出的链接中复制了示例。
try {
URL a = new URL(args[0]);
URLConnection urlc = a.openConnection();
is = conn.getInputStream();
int ret = 0;
while ((ret = is.read(buf)) > 0) { // here it try to read response using existing connection.
processBuf(buf);
}
// close the inputstream
is.close();
} catch (IOException e) {
try {
respCode = ((HttpURLConnection)conn).getResponseCode();
es = ((HttpURLConnection)conn).getErrorStream();
int ret = 0;
// read the response body
while ((ret = es.read(buf)) > 0) {
processBuf(buf);
}
// close the errorstream
es.close();
} catch(IOException ex) {
// deal with the exception
}
}
使用上面显示的技术加载日志文件。
以下是一个很好的解释:Persistent Connection
另一种选择很简单,考虑制作Ajax Request
。