记Weblogic部署BUG(websocket)

将含有websocket的SSM项目部署在Weblogic上面,遇到websocket报错以下java

java.lang.ClassCastException: org.springframework.session.web.http.SessionReposi
toryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper cannot be cast to
weblogic.servlet.security.internal.SessionSecurityData
        at weblogic.servlet.security.internal.SecurityModule.getCurrentUser(Secu
rityModule.java:197)
        at weblogic.websocket.tyrus.TyrusServletFilter.doFilter(TyrusServletFilt
er.java:167)
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
va:78)
        at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(Abst
ractInstrumentedFilter.java:104)
        at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
va:78)
        Truncated. see log file for complete stacktrace

 直观看,是类型转换错误,发生在weblogic的对象中.web

能够搜到的相似问题中,都在尝试将/websocket排除在web.xml中的filter以外,而这边遇到的项目,这么作不现实,因此开始分析该bugspring

 

思路:websocket

1.DEBUG获取到出错的 filterChain,发现weblogic自行追加了一个fitler,叫TyrusServletFilter,错误在这个Filter中发生.session

2.从weblogic的安装目录中找到TyrusServletFilter的jar包,引入到IDEA,准备反编译看源码app

3.根据上面的报错,错误发生在SecurityModule中的getCurrentUser中,打断点DEBUG肯定到具体行:socket

上图是TyrusServletFilter的反编译代码,红线处可看到,进入出错代码的条件代理

具体出错行,很是明了的强制转换,转换了request.getSession的结果xml

 

4.在该处进行DEBUG(竟然真的能DEBUG),发现正常的时候,getCurrentUser的request参数是一个ServletRequestImpl对象(来自weblogic),而出错时,request参数是一个SecurityContextHolderAwareRequestWrapper对象,故肯定问题是包装问题(即包装器的getSession并无代理好其内部request的getSession方法)对象

 

 

解决方案:

肯定了出错的包装类后,要重写并覆盖该类,代码以下:

该包装类本来并无覆盖getSession方法,这里添加覆盖,加入和TyrusServletFilter中相同的判断逻辑,

若是符合条件,则就地一层一层拆包装,拆到ServletRequestImpl为止.再调用ServletRequestImpl的getSession返回出结果.

若是不符合条件,不作改变.

 

 

这大概是解决该问题的另外一套思路了.

我这里因为使用了SpringSecurity,故要作修改的是SecurityContextHolderAwareRequestWrapper

若是使用了别的filter,那么能够覆盖其余的requestWrapper

固然最简单的方案仍是在web.xml中将/websocket排除在全部filter外,若是不能够的话,再按我这个思路作改动

相关文章
相关标签/搜索