看台湾林信良的《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不能正确响应,后台也不报错
不知道什么原因,记录下 以后解决