2017-01-23 122 views
2

我已经对我即将提出的问题有了一个答案。Weblogic 12.2.1.2 - websocket端点 - 此请求禁用异步支持

在任何casse中,我都这样问,以便它可以帮助人们从JEE 6迁移到JEE 7,并且正在考虑使用websocket - 例如用websocket功能替代长轮询。

问题: 在WebLogic 12.2.1.2,它支持JEE 7,和使用导如下面试图安装的WebSockets: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/WebsocketHome.html

注意:上面的指南是极其简单和所有它说的是正确和“应该”工作。不会在您的应用程序中工作,因为它不在我的应用程序中。但在概念上它应该。

尽管如此。 在浏览器到备份的握手期间,websocket应用程序出现错误,HTTP连接应该升级到tcp/ip web套接字连接。 Weblogic,抱怨Tyrus不能使用Ascyn servlet行为来处理这个握手协议。 为握手期间错误的堆栈跟踪旁边列出:

2017年1月23日14:54:59065的ThreadId:53 ERROR HTTP - [ServletContext的@ 129852715 [应用程式:primefaces-60模块:primefaces-60

路径:空规格版本:3.1]] Servlet的失败,一个异常 < [有效] ExecuteThread: '5' 的队列: 'weblogic.kernel.Default(自调谐)'> java.lang.IllegalStateException :异步支持在此 请求上被禁用:[email protected] [GET /primefaces-60/actions HTTP/1.1连接:升级Pragma:no-cache Cache-Control:no-cache升级:websocket来源: http://localhost:7001 Sec-WebSocket-Version:13用户代理: Mozilla/5.0(Windows NT 6.1; WOW64)AppleWebKit/537.36(KHTML,类似于 Gecko)Chrome/55.0.2883.87 Safari/537.36 DNT:1 Accept-Encoding:gzip, deflate,sdch,br Accept-Language: zh-CN,en; q = 0.8, pt-PT; q = 0.6,pt; q = 0.4,fr; q = 0.2,it; q = 0.2,de; q = 0.2 012-32-放气; client_max_window_bits

]在 weblogic.servlet.internal.ServletRequestImpl.startAsync(ServletRequestImpl.java:2029) 在 weblogic.servlet.internal.ServletRequestImpl.startAsync(ServletRequestImpl.java:2005) 在 的javax.servlet。 ServletRequestWrapper.startAsync(ServletRequestWrapper.java:432) 在 weblogic.websocket.tyrus.TyrusServletFilter.doFilter(TyrusServletFilter.java:241) 在 weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78) 在filter.DummyTimeoutFilter2.doFilter(DummyTimeoutFilter2.java:81) at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78) 在 weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:32) 在 weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl .java:78) at weblogic.servlet.internal.WebAppServletContext $ ServletInvocationAction。wrapRun(WebAppServletContext.java:3683) 在 weblogic.servlet.internal.WebAppServletContext $ ServletInvocationAction.run(WebAppServletContext.java:3649) 在 weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326) 在 weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197) 在 weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203) 在 weblogic.servlet.provider.WlsSubjectHandle.run (WlsSubjectHandle.java:71) at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2433) 在 weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2281) 在 weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2259) 在 weblogic.servlet.internal.ServletRequestImpl.runInternal (ServletRequestImpl.java:1691) 在 weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1651) 在 weblogic.servlet.provider.ContainerSupportProviderImpl $ WlsRequestExecutor.run(ContainerSupportProviderImpl.java:270) 在 weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:348) 在 weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333) 在 weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:54) 在 weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41) 处 weblogic.work.ExecuteThread.run(ExecuteThread.java:346) weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:640) 在weblogic.work.ExecuteThread.execute(ExecuteThread.java:406)

基于以下假设:设置websocket端点的后端代码是完美的,用于尝试建立websocket连接的javascript代码是完美的。 可以根据信件的指导说明为什么会得到上述错误?

注意: - 上面的堆栈跟踪已在示例应用程序中隔离,该应用程序基于对实际应用程序的分析,将工作websocket端点破坏为上述异常。

答案很简单,一旦你知道它... 我会在一天左右回答,如果没有人回到正确的解决方案。

回答

2

回答我自己的问题。

应用程序在尝试打开web-socket连接时遇到的问题与tyrus使用Sevlet 3.0 specificaiton的功能(即异步servlet处理)有关。

即使在最琐碎的Web应用程序中,也可能有过滤器适用于所有Web请求。 如过滤器映射/ *。

那么恰恰是这个问题。 正如以下参考文献中所述,为了允许异步servlet运行引导到servlet的完整过滤器链,必须它们支持异步请求处理。

https://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3

是需要的,asyncSupported属性区分书面 用于同步处理从用于在 异步上下文中使用而编写的代码。实际上,对于使用异步功能的应用程序,整个请求处理链必须具有 ,通过注释或其部署描述符设置此属性。如果 应用程序尝试启动异步操作,并且请求处理链中存在 servlet或servlet筛选器,并且 不支持异步处理,则会抛出IllegalStateException异常。

因此,要解决这个问题,所述组滤波器必须被给予额外的元件:

<async-supported>true</async-supported> 

例如:

<filter> 
    <filter-name>AFilter</filter-name> 
    <filter-class>webapp.AFilter</filter-class> 
    <async-supported>true</async-supported> 
</filter> 

在堆栈跟踪的情况下,上述,使问题在独立应用程序中可重现所需的一切就是添加一个虚拟过滤器,除了将请求传递给下一个过滤器外,它绝对没有任何问题。 过滤器是:DummyTimeoutFilter2。 此过滤器被声明为不支持异步支持true。

因此,总结一下,请注意,您的容器可能需要异步servlet才能打开Web套接字。如果您有任何过滤器将请求发送给您的websocket端点,您可能会对这种副作用感到惊讶。 这对于JEE 6中出现的应用程序尤其如此,但它可能很容易发生在任何全新的JEE 7应用程序中。

然而,大多数人可能没有筛选器拦截呼叫websocket端点...