巨大的建筑,总是由一木一石叠起来的,我们何妨做做这一木一石呢?我时常做些零碎事,就是为此。
这是对的,但是我没有说过这句话! —— 鲁迅
代码如下,报错了:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//当调用了下面的startWebSocket函数后,该socket就会和相应的listener建立起对应关系
WebSocketListener listener = new MyWebSocketListener(myWebSocketService);
ShiroHttpServletRequest sr = (ShiroHttpServletRequest) req;
}
ShiroHttpServletRequest sr = (ShiroHttpServletRequest) req;
这个request的类型是 HttpServletRequest
,强制转换成 ShiroHttpServletRequest
报错,这是之前的代码,肯定没问题,说明这个request本身就是 ShiroHttpServletRequest
跟一下代码,发现HttpServletRequest
是如何一步步的变成ShiroHttpServletRequest
的。
AbstractShiroFilter中有如下代码:
protected ServletRequest wrapServletRequest(HttpServletRequest orig) {
return new ShiroHttpServletRequest(orig, getServletContext(), isHttpSessions());
}
是在这里进行了一层包裹,重建,生成的,具体调用路径,经分析为如下:
DelegatingFilterProxy(invokeDelegate)->
OncePerRequestFilter(doFilter)->
AbstractShiroFilter(doFilterInternal->prepareServletRequest->wrapServletRequest)
现在就定位到了DelegatingFilterProxy
,查看之前的代码,DelegatingFilterProxy
的定义是在web.xml中定义的,如下:
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>staticSecurityManagerEnabled</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
解决方法:将这个DelegatingFilterProxy转换为spring-boot的方式。如下:
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean<DelegatingFilterProxy> delegatingFilterProxy() {
FilterRegistrationBean<DelegatingFilterProxy> filterRegistrationBean = new FilterRegistrationBean<>();
DelegatingFilterProxy shiroFilter = new DelegatingFilterProxy();
filterRegistrationBean.setFilter(shiroFilter);//注入的bean不为null
filterRegistrationBean.addUrlPatterns("/*");//配置过滤规则
filterRegistrationBean.setName("shiroFilter");
filterRegistrationBean.setOrder(2);//执行次序
return filterRegistrationBean;
}
}
重新启动,则可以正常