首先,102 PROCESSING 状态在以下情况下似乎很有用:
该操作运行时间很长,例如,一些复杂的级联数据库删除操作,或者在 WebDAV 上,一个大目录深拷贝等。
我需要这个,因为在某些环境中访问是通过防火墙并且有 5 分钟超时。如果超过 5 分钟没有通过 TCP 连接,则连接关闭。在服务器端这显示为 IOError 连接关闭,在客户端这也显示为连接关闭或超时错误消息。
我们使用 102 PROCESSING 是因为在我们可以写入 servlet 输出流之前,我们需要保持我们的选项打开以仍然以最终的 200、300(重定向)或 400(错误)回复。
102 PROCESSING 确实没有得到很好的支持。 JETTY(服务器)有一些基本的实现,我用一个单独的线程在它上面制作了一些东西,它会休眠 5 分钟,检查 servlet 输出流是否仍未提交,然后发出 response.sendProcessing() 并再次进入休眠状态。一旦写入实际输出,线程就会被终止。
Apache HTTPD 如果用作此 JETTY 实现的反向代理,则可以很好地传递这 102 个 PROCESSING 响应。但是在其中的 10 个之后,它会引发错误。
sun.net.www.protocol.http.HttpURLConnection 不能很好地处理这个问题。我有一个小测试程序:
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.io.*;
public class urlcontest {
public static void main(String args[]) throws Exception {
URLConnection conn = new URL(args[0]).openConnection();
System.err.println("URLConnection class: " + conn.getClass());
if(args.length > 1)
conn.setRequestProperty("Cookie",args[1]);
conn.setAllowUserInteraction(false);
conn.setDoOutput(false);
conn.setDoInput(true);
InputStream in = null;
if(conn instanceof HttpURLConnection) {
HttpURLConnection hconn = (HttpURLConnection)conn;
int responseStatus = hconn.getResponseCode();
try {
in = hconn.getInputStream();
System.err.println("HTTP input: " + responseStatus);
} catch(IOException e) {
System.err.println("HTTP error: " + responseStatus);
in = ((HttpURLConnection)conn).getErrorStream();
}
} else
in = conn.getInputStream();
byte[] buf = new byte[4096];
int nread = 0;
while((nread = in.read(buf)) > 0)
System.out.write(buf, 0, nread);
in.close();
}
}
有了这个,我得到以下行为:
URLConnection class: class sun.net.www.protocol.http.HttpURLConnection
HTTP input: 102
HTTP/1.1 102 Processing
HTTP/1.1 102 Processing
HTTP/1.1 102 Processing
HTTP/1.1 301 Moved Permanently
Location: ...
Content-Type: text/html
Content-Length: ...
Server: Jetty(6.0.1)
<html>...</html>
因此,很明显,它将第一个 102 PROCESSING 作为最终响应,然后从输入流中读取其他所有内容,并在暂停期间阻塞。
如果我能找到这个或另一个 HttpURLConnection 实现的源代码,我会做一些事情让它工作。
不知何故,它也应该已经处理了 100 CONTINUE 响应。做起来应该不会太难。