版本信息:
Spring:4.3.10
最近遇到一个功能点,需要在 Controller 未接收到请求之前,添加请求携带的参数。在询问多位网友开发者,他们推荐使用 Filter,并且建议我读 Shiro 的源码(这源码之前读过,没看懂,哈哈~)。
第一次尝试:
public class LoginFilter implements Filter{
@Autowired
private Service Service;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
int uid = Service.getUid(cert);
request.setAttribute("uid", String.valueOf(uid));
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
结论:失败告终,Service注入失败,为null。原因是因为 Filter 运行在 Spring注入bean之前,导致Filter 内注入的值为 null。
第二次尝试:
private Services service;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if(service==null){
ServletContext servletContext = request.getServletContext();
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
service = webApplicationContext.getBean(Services.class);
}
int uid = Service.getUid(cert);
request.setAttribute("uid", String.valueOf(uid));
chain.doFilter(request, response);
}
结论:失败;
第三次尝试:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
int uid = Service.getUid(cert);
request.setAttribute("uid", String.valueOf(uid));
chain.doFilter(request, response);
}
结论:失败;
.
.
.
后来我看到很多人推荐 利用 org.springframework.web.filter.DelegatingFilterProxy 来把 Filter 注入到Spring中,于是就有了 第n次、第n+1次尝试。
第n+1次尝试:
web.xml
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring-servlet.xml
<bean id="loginFilter" class="com.xxxxx.xxxxx.filter.LoginFilter"></bean>
结论:完美;
参考:
https://stackoverflow.com/questions/30554688/get-the-autowired-service-in-filter-class
https://stackoverflow.com/questions/32127258/how-to-autowire-bean-in-the-servlet-filters-in-spring-application
http://learningviacode.blogspot.com/2013/12/delegatingfilterproxy-and-spring.html
https://stackoverflow.com/questions/32494398/unable-to-autowire-the-service-inside-my-authentication-filter-in-spring
在过滤器内,通过request.setAttribute方法添加的参数,现在发现只能通过request.getAttribute方法获取。若通过框架直接在方法参数内写入key值获取,获取到的值为null。
这样通过HttpServletRequest 获取是可以的。
下面这样获取,是获取不到值得。
谢谢