tomcat异步servlet处置上传数据超时,chrome显示连接已重置

tomcat异步servlet处理上传数据超时,chrome显示连接已重置
昨天刚学习servlet3.1的异步处理,据说这个对性能有很大提升,第一个想到能应用的地方就是耗时的上传了,写了几个测试代码,普通get、post访问均正常,超时了也能显示超时后的错误处理内容,唯独关键的文件上传,当超时后浏览器怎么也不显示我输出的错误处理内容,chrome里直接显示“与 localhost 的连接已中断.....错误 101 (net::ERR_CONNECTION_RESET):连接已重置。”,这个不知道是我代码的原因还是tomcat对这个请求进行了特殊处理

上传测试代码:

import java.io.IOException;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(value="/test", asyncSupported=true)
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExceptionIOException {
response.setContentType("text/html; charset=utf-8");
response.getWriter().append("上传post:<form action='/test' method='post' enctype='multipart/form-data'>")
.append("<input type='text' value='a' name='a'>")
.append("<input type='file' name='fileadd'>")
.append("<input type='file' name='fileadd'>")
.append("<input type='text' value='b' name='b'>")
.append("<input type='submit' value='submit'>")
.append("</form>");

response.getWriter().append("普通post:<form action='/test' method='post'>")
.append("<input type='text' value='a' name='a'>")
.append("<input type='text' value='b' name='b'>")
.append("<input type='submit' value='submit'>")
.append("</form>");
}


protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost:Thread"+Thread.currentThread().getId());
System.out.println(request.getMethod()+":"+request.getRequestURL());
System.out.println("ContentType:"+request.getContentType());

response.setContentType("text/html; charset=utf-8");
response.getWriter().println("这个是测试");

Exec exec=new Exec(request, response);

//开启异步处理
AsyncContext ctx=request.startAsync();
ctx.setTimeout(1000);
ctx.addListener(exec);

//启动异步处理线程
ctx.start(exec);

System.out.println("doPost End:Thread"+Thread.currentThread().getId());
}

/**
 * 请求异步处理
 */
static public class Exec implements Runnable, AsyncListener{
HttpServletRequest request;
HttpServletResponse response;
Thread thread;
public Exec(HttpServletRequest request, HttpServletResponse response){
this.request=request;
this.response=response;
}

public void run(){
thread=Thread.currentThread();

//post上传数据处理
try(ServletInputStream in=request.getInputStream()){
System.out.println("upload start:Thread"+Thread.currentThread().getId());

byte[] byts=new byte[16*1024];
while(in.readLine(byts, 0, byts.length)!=-1){
try {
Thread.sleep(20);//上传限速
} catch (InterruptedException e) {
thread.interrupt();
}

if(thread.isInterrupted()){
System.out.println("上传被中断:Thread"+Thread.currentThread().getId());
return;
}
}

//普通Post等待超时
if(request.getContentType().toLowerCase().indexOf("multipart")==-1){
try{
Thread.sleep(2000);
}catch(InterruptedException e){
thread.interrupt();
return;
}
}

System.out.println("upload end:Thread"+Thread.currentThread().getId());
}catch(IOException e){
System.out.println("upload error:Thread"+Thread.currentThread().getId());
}finally{
if(thread.isInterrupted()){
return;
}

thread=null;

System.out.println("call complete:Thread"+Thread.currentThread().getId());

//正常提交响应
request.getAsyncContext().complete();
}
}


//--------------------------------------------------------------------

@Override
public void onComplete(AsyncEvent arg0) throws IOException {
System.out.println("onComplete:Thread"+Thread.currentThread().getId());
}

@Override
public void onTimeout(AsyncEvent arg0) throws IOException {
System.out.println("onTimeout:Thread"+Thread.currentThread().getId());

if(!response.isCommitted()){
response.resetBuffer();//清空缓冲区
}

response.setStatus(408);
response.getWriter().print("!!!!Timeout!!!!");

//中断处理线程
if(thread!=null){
thread.interrupt();
}
}

@Override
public void onError(AsyncEvent arg0) throws IOException {