使用 spring 容器管理 Filter

来源:互联网 发布:mysql pxc 架构 编辑:程序博客网 时间:2024/04/30 06:47

使用 spring 容器管理 Filter


        《使用 Spring 容器管理 Servlet》一文介绍了如何使用 Spring 对 Servlet 进行管理,本文是《使用 Spring 容器管理 Servlet》的姊妹篇,本文介绍如何使用 Spring 对 Filter 进行管理。其实具体原理方法和前者大同小异。

        如一般的 J2EE 配置一样,Spring 在 web.xml 中的配置:

[html] view plain copy
 print?
  1. <listener>  
  2.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  3. </listener>  
  4. <context-param>  
  5.     <param-name>contextConfigLocation</param-name>  
  6.     <param-value>/WEB-INF/applicationContext*.xml</param-value>  
  7. </context-param>  


        如一般的 J2EE 配置一样,Spring 在 applicationContext-service.xml 中定义我们的业务逻辑处理类:

[html] view plain copy
 print?
  1. <bean id="logService"  
  2.     class="com.defonds.cds.system.log.impl.LogServiceImpl"  
  3.     parent="baseService" scope="singleton" init-method="init" destroy-method="destroy">  
  4. </bean>  


        如同一般的 Struts1/2 的 action 一样在我们的 Filter 中注入 service:

[java] view plain copy
 print?
  1. private LogService logService;  
  2. public LogService getLogService() {  
  3.     return logService;  
  4. }  
  5.   
  6. public void setLogService(LogService logService) {  
  7.     this.logService = logService;  
  8. }     


        在 Filter 中如同一般的 Struts1/2 的 action 一样调用 service:

[java] view plain copy
 print?
  1. String ip = logService.getIpAddr(request);  


        如同一般的 Filter 我们的这个 Filter 需要实现 javax.servlet.Filter 接口:

[java] view plain copy
 print?
  1. public class BlockedIpFilter implements Filter {  


        根据自己的业务需要去实现 init、doFilter 和 destroy 方法:

[java] view plain copy
 print?
  1. @Override  
  2. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,  
  3.         FilterChain filterChain) throws IOException, ServletException {  
  4.     if (ifIpBlocked) {  
  5.         HttpServletRequest request = (HttpServletRequest)servletRequest;  
  6.         HttpServletResponse response = (HttpServletResponse) servletResponse;    
  7.         String ip = logService.getIpAddr(request);  
  8.           
  9.         if (logService.ifBlocked(ip)) {  
  10.             response.getWriter().write("error");  
  11.             response.getWriter().close();  
  12.         } else {  
  13.             filterChain.doFilter(request, response);  
  14.         }  
  15.     } else {  
  16.         filterChain.doFilter(servletRequest, servletResponse);  
  17.     }  
  18.   
  19. }  
  20.   
  21. @Override  
  22. public void init(FilterConfig arg0) throws ServletException {  
  23.     // TODO Auto-generated method stub  
  24. }  
  25.   
  26. @Override  
  27. public void destroy() {  
  28.     // TODO Auto-generated method stub  
  29. }  


        新建一个 Filter 代理类,这个类类似于 DelegatingFilterProxy 那样的代理,通过代理根据配置来找到实际的 Filter,完成业务逻辑功能:

[java] view plain copy
 print?
  1. package com.defonds.cds.system.log.filter;  
  2.   
  3. import java.io.IOException;  
  4.   
  5.   
  6. import javax.servlet.Filter;  
  7. import javax.servlet.FilterChain;  
  8. import javax.servlet.FilterConfig;  
  9. import javax.servlet.ServletContext;  
  10. import javax.servlet.ServletException;  
  11. import javax.servlet.ServletRequest;  
  12. import javax.servlet.ServletResponse;  
  13.   
  14. import org.springframework.web.context.WebApplicationContext;  
  15. import org.springframework.web.context.support.WebApplicationContextUtils;  
  16.   
  17.   
  18. //Filter 的代理类。系统所有的 Filter 共用此一个  
  19. public class DelegatingFilterProxy implements Filter {  
  20.     private String targetFilterBean;  
  21.     private Filter proxy;  
  22.   
  23.     @Override  
  24.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,  
  25.             FilterChain filterChain) throws IOException, ServletException {  
  26.         proxy.doFilter(servletRequest, servletResponse, filterChain);  
  27.     }  
  28.   
  29.     @Override  
  30.     public void init(FilterConfig config) throws ServletException {  
  31.         this.targetFilterBean = config.getInitParameter("targetFilterBean");  
  32.         ServletContext servletContext = null;  
  33.         servletContext = config.getServletContext();  
  34.         WebApplicationContext wac = null;  
  35.         wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);  
  36.         this.proxy = (Filter) wac.getBean(this.targetFilterBean);  
  37.         this.proxy.init(config);  
  38.     }  
  39.   
  40.     @Override  
  41.     public void destroy() {}  
  42. }  


        不同于一般的 Filter 在 web.xml 中的配置,需要配置的是 Filter 代理类,而非 Filter:

[html] view plain copy
 print?
  1. <filter>  
  2.     <filter-name>proxyBlockedIpFilterBean</filter-name>  
  3.     <filter-class>com.defonds.cds.system.log.filter.DelegatingFilterProxy</filter-class>  
  4.     <init-param>  
  5.         <param-name>targetFilterBean</param-name>  
  6.         <param-value>blockedIpFilterBean</param-value>  
  7.     </init-param>  
  8. </filter>  
  9. <filter-mapping>  
  10.     <filter-name>proxyBlockedIpFilterBean</filter-name>  
  11.     <url-pattern>/*</url-pattern>  
  12. </filter-mapping>  


        最后在 applicationContext-service.xml 中将 Filter 及其业务对象的依赖关系配置到 Spring 容器管理:

[html] view plain copy
 print?
  1. <bean id="blockedIpFilterBean" class="com.defonds.cds.system.log.filter.BlockedIpFilter">  
  2.     <property name="logService">  
  3.         <ref bean="logService"/>  
  4.     </property>  
  5. </bean>  


        注意这里的 blockedIpFilterBean 要和 web.xml 配置的 blockedIpFilterBean 对应,logService 要和 Filter 中 get/set 得到的 logService bean 对应。
0 0