2017-02-22 21 views
0

环境:上的servlet请求调用startAsync()抛出IllegalStateException异常由码头9的ProxyServlet的终止的过滤器链

  • 在我的环境,Kibana 4.5.2运行后面“反向代理servlet”,其是通过扩展Jetty的“ProxyServlet”类创建的。
  • 这样做是为了使用URL https://Jetty_Server_IP:8443/visual-analytics/proxy/ ...可以访问Kibana网页界面。该URL的请求被在Jetty服务器中运行的反向代理拦截,并被重定向到https://localhost:5601/ ...即,到Kibana服务器与Jetty服务器在同一台机器上运行。
  • Kibana服务器然后处理由Jetty服务器转发的请求并将响应返回给Web浏览器。
  • 注意: Jetty在我的应用程序中以“嵌入模式”运行。

问题:

“反向代理servlet” 被映射到URL “/视觉分析/代理/ *”。

有被映射到其中由下面的代码段所指示正在使用ContinuationListener的URL“/visual-analytics/proxy/elasticsearch/.kibana/search/*”另一个“过滤器”:

ContinuationSupport.getContinuation(myRequestWrapper).addContinuationListener(new ContinuationListener() { 

         @Override 
         public void onTimeout(Continuation continuation) { 
          logger.log(Level.WARNING, "Request timeout..."); 
         } 

         @Override 
         public void onComplete(Continuation continuation) { 

          HttpServletResponse httpResponse = (HttpServletResponse)continuation.getServletResponse(); 
          if (httpResponse.getStatus() == HttpServletResponse.SC_OK || httpResponse.getStatus() == HttpServletResponse.SC_CREATED) { 
            //some business logic 
          } 

         } 
        }); 

    chain.doFilter(myRequestWrapper, response); 

以上ContinuationListener工作正常与码头版本8.1.15.v20140411与收听者的onComplete()方法被调用。但是在将Jetty版本升级到9.3.14.v20161028后,ContinuationListener不再工作,即既没有调用监听器的onComplete()方法也没有调用onTimeout()方法。

由于ContinuationListener不再工作,我用“javax.servlet.AsyncListener”的实施方案替换其通过下面的代码片段所示:

   AsyncContext asyncContext = myRequestWrapper.startAsync(); 
       asyncContext.addListener(new AsyncListener() { 

        @Override 
        public void onTimeout(AsyncEvent event) throws IOException 
        { 
           logger.log(Level.WARNING, "Async timeout..."); 
        } 

        @Override 
        public void onStartAsync(AsyncEvent event) throws IOException 
        { 
           logger.log(Level.INFO, "Async start..."); 
        } 

        @Override 
        public void onError(AsyncEvent event) throws IOException 
        { 
           logger.log(Level.SEVERE, "Async error..."); 
        } 

        @Override 
        public void onComplete(AsyncEvent event) throws IOException 
        { 
          HttpServletResponse httpResponse = (HttpServletResponse) event.getSuppliedResponse(); 
         //HttpServletResponse httpResponse = (HttpServletResponse) event.getAsyncContext().getResponse(); 
         if (httpResponse.getStatus() == HttpServletResponse.SC_OK || httpResponse.getStatus() == HttpServletResponse.SC_CREATED) { 
            //some business logic 
         } 
        } 
     }, myRequestWrapper, httpServletResponse); 

     chain.doFilter(myRequestWrapper, response); 

但加入上述“AsyncListener”的实施导致这是在上述第一提到

https://164.99.175.139:8443/visual-analytics/proxy/elasticsearch/.kibana/search/test1?op_type=create 
    java.lang.IllegalStateException: s=DISPATCHED i=true a=STARTED 
      at org.eclipse.jetty.server.HttpChannelState.startAsync(HttpChannelState.java:264) 
      at org.eclipse.jetty.server.Request.startAsync(Request.java:2235) 
      at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:432) 
      at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:432) 
      at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:432) 
      at org.eclipse.jetty.proxy.ProxyServlet.service(ProxyServlet.java:88) 
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
      at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845) 
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1712) 
      at com.netiq.sentinel.kibana.search.KibanaSearchFilter.doFilter(KibanaSearchFilter.java:249) 
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
      at com.netiq.sentinel.kibana.proxy.AcceptEncodingHeaderModificationFilter.doFilter(AcceptEncodingHeaderModificationFilter.java:37) 
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
      at com.netiq.sentinel.kibana.proxy.SecurityFilter.doFilter(SecurityFilter.java:41) 
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
      at com.netiq.sentinel.kibana.proxy.AuditFilter.doFilter(AuditFilter.java:104) 
      at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
      at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582) 
      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) 
      at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) 
      at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) 
      at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180) 
      at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512) 
      at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) 
      at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112) 
      at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 
      at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213) 
      at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119) 
      at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) 
      at org.eclipse.jetty.server.Server.handle(Server.java:534) 
      at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320) 
      at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) 
      at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) 
      at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) 
      at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:202) 
      at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) 
      at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) 
      at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) 
      at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) 
      at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) 
      at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) 
      at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) 
      at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) 
      at java.lang.Thread.run(Thread.java:745) 

行号88在 “ProxyServlet.java”:下面的 “IllegalStateException异常” ACK跟踪具有下面的代码:

final AsyncContext asyncContext = request.startAsync(); 

就是“IllegalStateException异常”被抛出,因为startAsync()方法正在对同一请求调用两次 - 在我的过滤器首次在码头第二次ProxyServlet的service()方法?如果是,是否没有办法在由Jetty的ProxyServlet终止的过滤器链中使用“AsyncListener”?

任何关于如何进一步进一步指针将不胜感激。期待任何回应...

回答

1

FYI我解决了这个问题,如下所示:

  1. 而不是使用Jetty的“ContinuationListener”的,我用的Servlet 3.0的“AsyncListener”,因为码头的“ContinuationListener”似乎并没有升级到后,开始工作码头9.3.14.v20161028。这可能是一个码头错误。
  2. 与侦听器相关的代码段位于筛选器的“chain.doFilter()”调用之前。我将此代码段移至过滤器的“chain.doFilter()”调用后面,以便我可以检索Jetty ProxyServlet的service()方法中“已创建”的AsyncContext。然后,我可以将AsyncListener添加到检索到的AsyncContext中。
  3. 我将过滤器中的“request.startAsync()”调用改为“request.getAsyncContext()”,这样我就不会启动一个新的AsyncContext而导致IllegalStateException,而只是检索已经创建的AsyncContext Jetty的ProxyServlet。

所以更新的代码段看起来是这样的:

  chain.doFilter(myRequestWrapper, response); 

      AsyncContext asyncContext = myRequestWrapper.getAsyncContext(); 
      asyncContext.addListener(new AsyncListener() { 

       @Override 
       public void onTimeout(AsyncEvent event) throws IOException 
       { 
          logger.log(Level.WARNING, "Async timeout..."); 
       } 

       @Override 
       public void onStartAsync(AsyncEvent event) throws IOException 
       { 
          logger.log(Level.INFO, "Async start..."); 
       } 

       @Override 
       public void onError(AsyncEvent event) throws IOException 
       { 
          logger.log(Level.SEVERE, "Async error..."); 
       } 

       @Override 
       public void onComplete(AsyncEvent event) throws IOException 
       { 
         HttpServletResponse httpResponse = (HttpServletResponse) event.getSuppliedResponse(); 
        //HttpServletResponse httpResponse = (HttpServletResponse) event.getAsyncContext().getResponse(); 
        if (httpResponse.getStatus() == HttpServletResponse.SC_OK || httpResponse.getStatus() == HttpServletResponse.SC_CREATED) { 
           //some business logic 
        } 
       } 
    }, myRequestWrapper, httpServletResponse); 
相关问题