SSM框架中Filter使用@Autowired注入Service

版本信息:
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

0

一个有关“SSM框架中Filter使用@Autowired注入Service”的想法

  1. 在过滤器内,通过request.setAttribute方法添加的参数,现在发现只能通过request.getAttribute方法获取。若通过框架直接在方法参数内写入key值获取,获取到的值为null。

    这样通过HttpServletRequest 获取是可以的。

        public String bindEmail(HttpServletRequest request, String email, String password) {
            String uidStr = (String) request.getAttribute("uid");
        }
    
    

    下面这样获取,是获取不到值得。

        public String bindEmail(String uid, String email, String password) {
    
        }
    
    
    0

发表评论

This site uses Akismet to reduce spam. Learn how your comment data is processed.