java.lang.IllegalStateException:在AsyncContext#complete()时未挂起 [英] java.lang.IllegalStateException: Not Suspended when AsyncContext#complete()

查看:280
本文介绍了java.lang.IllegalStateException:在AsyncContext#complete()时未挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 警告:StandardWrapperValve [HeartBeatServlet]:PWC1406:Servlet.service()for servlet HeartBeatServlet抛出异常
java.lang.IllegalStateException:未暂挂
在com.sun.grizzly.tcp.Response.resume(Response.java:768)
在org.apache.catalina。 connector.Request.asyncComplete(Request.java:3993)
在org.apache.catalina.connector.AsyncContextImpl.complete(AsyncContextImpl.java:242)
在com.northcane.talkeen.HeartBeatServlet.doPost(在javax.servlet.http.HttpServlet.service HeartBeatServlet.java:47)
在javax.servlet.http.HttpServlet.service(HttpServlet.java:688)
(HttpServlet.java:770)$ b在org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
$ b在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
。在组织.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.j ava:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
在com.sun.enterprise.v3.services.impl.ContainerMapper $ AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com .sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:在com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137 229)

在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
。在COM .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
在com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
在com.sun.grizzly.ProtocolChainContextTask .doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71 )
at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513 )
在java.lang.Thread.run(Thread.java:722)

和这是我的Servlet的来源。它所做的唯一的事情就是处理来自javascript客户端的长轮询请求,并将发送的邮件发送到所有人:

  import java.io.IOException; 
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.AsyncContext;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet(名称= HeartBeatServlet,URL模式= { / HeartBeatServlet},asyncSupported =真)
公共类HeartBeatServlet延伸的HttpServlet {

私人列表< AsyncContext> asyncContextList = new LinkedList<>();
$ b $ @Override
public void doGet(HttpServletRequest request,HttpServletResponse response){
AsyncContext asyncContext = request.startAsync(request,response);
asyncContext.setTimeout(30000);
asyncContextList.add(asyncContext);

$ b @Override
public void doPost(HttpServletRequest请求,HttpServletResponse响应){
String test = request.getParameter(message);
List< AsyncContext> asyncContexts = new ArrayList<>(asyncContextList);
asyncContextList.clear(); (AsyncContext asyncContext:asyncContexts)
{
ServletResponse res = asyncContext.getResponse();
res.setContentType(text / html);
尝试{
PrintWriter out = asyncContext.getResponse()。getWriter();
out.println(test +< br />);
out.flush();
asyncContext.complete();
} catch(IOException e){
e.printStackTrace();




$ / code $ / pre

是我有什么不对吗?谢谢

解决方案

(代码有多线程问题,请参阅

代码将一个GET请求的AsyncContext存储在一个List中,在POST上完成GET响应。但由于超时,GET响应可能已隐式完成(由servlet容器触发),并且存储的AsyncContext不会反映这一点。因此,当您检索此存储的AsyncContext并尝试完成GET请求时,servlet容器不会找到需要恢复的待处理 GET请求。因此IllegalStateException。



请参考这个其他回答间接地回答了这个问题。


sometimes my Servlet ends with this exception:

    WARNING: StandardWrapperValve[HeartBeatServlet]: PWC1406: Servlet.service() for servlet HeartBeatServlet threw exception
java.lang.IllegalStateException: Not Suspended
    at com.sun.grizzly.tcp.Response.resume(Response.java:768)
    at org.apache.catalina.connector.Request.asyncComplete(Request.java:3993)
    at org.apache.catalina.connector.AsyncContextImpl.complete(AsyncContextImpl.java:242)
    at com.northcane.talkeen.HeartBeatServlet.doPost(HeartBeatServlet.java:47)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:688)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)

and here's my Servlet's source. The only thing it does is to handle long-polling requests from javascript client and sends message received on POST to all of them:

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.AsyncContext;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet(name = "HeartBeatServlet", urlPatterns = {"/HeartBeatServlet"}, asyncSupported = true)
public class HeartBeatServlet extends HttpServlet {

    private List<AsyncContext> asyncContextList = new LinkedList<>();

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        AsyncContext asyncContext = request.startAsync(request, response);
        asyncContext.setTimeout(30000);
        asyncContextList.add(asyncContext);
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) {
        String test = request.getParameter("message");
        List<AsyncContext> asyncContexts = new ArrayList<>(asyncContextList);
        asyncContextList.clear();
        for (AsyncContext asyncContext : asyncContexts) {
            ServletResponse res = asyncContext.getResponse();
            res.setContentType("text/html");
            try {
                PrintWriter out = asyncContext.getResponse().getWriter();
                out.println(test + " <br />");
                out.flush();
                asyncContext.complete();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

is there something wrong I do? Thanks

解决方案

(The code has Multi-threading issues. Pls see this SO answer for how to resolve them.)

The code is storing the AsyncContext for a GET request in a List and on a POST completes the GET response. But because of the timeout, the GET response may have completed implicitly (triggered by the servlet container) and the stored AsyncContext will not reflect this. So, when you retrieve this stored AsyncContext and try to complete the GET request, the servlet container does not find a pending GET request that needs to be resumed. Hence the IllegalStateException.

Pls also refer this other answer which indirectly answers this.

这篇关于java.lang.IllegalStateException:在AsyncContext#complete()时未挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆