servlet启用gzip过滤器后AsyncContext异步不成功的的问题

阅读更多

看台湾林信良的《JSP&Servlet学习笔记第二版》5.4节异步处理时遇到的问题

异步处理的servlet若存在过滤器,则过滤器的注解@WebFilter应设置asyncSupported=true,

否则会报错A filter or servlet of the current chain does not support asynchronous operations.

但是启用了gzip压缩过滤器的话(也是本书中的例子)异步处理结果不显示

@WebServlet(name="AsyncServlet", urlPatterns={"/async.do"},
	asyncSupported=true
)
public class AsyncServlet extends HttpServlet {
	
	private ExecutorService executorService = Executors.newFixedThreadPool(10);
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			    throws ServletException, IOException{
		response.setContentType("text/html;charset=UTF-8");
		AsyncContext actx = request.startAsync();
		executorService.submit(new AsyncRequest(actx));
	}
	
	@Override
	public void destroy(){
		executorService.shutdown();
	}
}

 AsyncRequest代码如下

public class AsyncRequest implements Runnable {

	private AsyncContext actx;
	
	public AsyncRequest(AsyncContext actx){
		this.actx = actx;
	}
	
	@Override
	public void run() {
		try {
			Thread.sleep(5000);
			PrintWriter out = actx.getResponse().getWriter();
			out.println("久等了。。。。这是异步执行的结果");
			out.close();
			actx.complete();
		} catch (Exception e) {
			 e.printStackTrace();    
		}
	}

}

 CompressionFilter如下

/*@WebFilter(filterName="CompressionFilter", urlPatterns={"/*"},
	asyncSupported=true
)*/
public class CompressionFilter implements Filter {
    public void init(FilterConfig filterConfig) {}

    public void doFilter(ServletRequest request,
                              ServletResponse response,
                            FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        String encodings = req.getHeader("accept-encoding");
        if ((encodings != null) && (encodings.indexOf("gzip") > -1)) {
            CompressionWrapper responseWrapper =
                    new CompressionWrapper(res);
            responseWrapper.setHeader("content-encoding", "gzip");

            chain.doFilter(request, responseWrapper);

            GZIPOutputStream gzipOutputStream =
                    responseWrapper.getGZIPOutputStream();
            if (gzipOutputStream != null) {
                gzipOutputStream.finish();
            }
        }
        else {
            chain.doFilter(request, response);
        }
    }

    public void destroy() {}
}

 wrapper代码如下

public class CompressionWrapper
                            extends HttpServletResponseWrapper {
    private GZipServletOutputStream gzServletOutputStream;
    private PrintWriter printWriter;

    public CompressionWrapper(HttpServletResponse resp) {
        super(resp);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        if(printWriter != null) {
            throw new IllegalStateException();
        }
        if (gzServletOutputStream == null) {
            gzServletOutputStream = new GZipServletOutputStream(
                    getResponse().getOutputStream());
        }
        return gzServletOutputStream;
    }

    @Override
    public PrintWriter getWriter() throws IOException {
        if(gzServletOutputStream != null) {
            throw new IllegalStateException();
        }

        if (printWriter == null) {
            gzServletOutputStream = new GZipServletOutputStream(
                     getResponse().getOutputStream());
            OutputStreamWriter osw = new OutputStreamWriter(
                      gzServletOutputStream,
                      getResponse().getCharacterEncoding());
            printWriter = new PrintWriter(osw);
        }
        return printWriter;
    }

    @Override
    public void setContentLength(int len) {}

    public GZIPOutputStream getGZIPOutputStream() {
        if (this.gzServletOutputStream == null) {
            return null;
        }
        return this.gzServletOutputStream.getGzipOutputStream();
    }
}

 当然,我还启用了其他几个filter,asyncSupported都设置为true,其他的过滤器都没问题,只有加上这个gzip过滤器(去掉@webfilter注解的注释),请求async.do不能正确响应,后台也不报错 

不知道什么原因,记录下 以后解决

 

 

你可能感兴趣的:(AsyncContext,异步,GZIP)