以此之長,補彼之短----AOP(Filter)

AOP(Aspect-Oriented Programming,面向切面編程),能夠說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP利用封裝、繼承和多態把一切事物打形成對象結構,可是對於全部對象中都存在的一些公共行爲,OOP就顯得無能爲力,抽象和接口雖好,但對全部不相干的對象創建共同的接口或父類未免有些生硬,例如日誌功能,日誌代碼幾乎散佈在全部的對象層次中,而它和散佈到對象的核心功能毫無關係,對於其餘類型的代碼,如安全性、異常處理和透明的持續性也是如此。所以,爲減小這種大量的重複代碼,面向切面技術誕生了,AOP和OOP的關係好似JSP和Servlet的關係,以此之長,補彼之短。 html

 

Java中常見的AOP技術有兩個,分別是Filter和代理模式,代理模式又分爲靜態代理和動態代理。他們各自實現的功能不一樣,原理一模一樣。以下圖,以添加用戶爲例,採用Module1架構模式,從圖中能夠看出不管程序從左向右或者從右向左執行都必須通過Filter,Filter在Request到達JSP(Servlet)前截獲Request並進行預處理,也能夠在Response離開JSP(Servlet)時處理Response,而後對Request進行統一的設置後繼續向後傳遞,好比能夠在Filter完成字符集的設置,用戶身份的識別,敏感詞彙的過濾等等,配置Filter個數不限。 java

下面就以設置字符集爲例,首先建立一個Class文件,並讓他實現Filter接口,覆寫init和doFilter,代碼以下: web

[java]   view plain copy print ?
  1. package com.snail.drp.util.filter;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11.   
  12. public class CharsetEncodingFilter implements Filter {  
  13.     private String endcoding;  
  14.       
  15.     @Override  
  16.     public void destroy() {  
  17.         // TODO Auto-generated method stub   
  18.     }  
  19.   
  20.     @Override  
  21.     public void doFilter(ServletRequest request, ServletResponse response,  
  22.             FilterChain chain) throws IOException, ServletException {  
  23.         request.setCharacterEncoding(endcoding);  
  24.           
  25.         //繼續執行   
  26.         chain.doFilter(request, response);    
  27.     }  
  28.   
  29.     @Override  
  30.     public void init(FilterConfig filterConfig) throws ServletException {  
  31.         this.endcoding = filterConfig.getInitParameter("encoding");  
  32.     }  
  33. }  
[java]   view plain copy print ?
  1. package com.snail.drp.util.filter;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.Filter;  
  6. import javax.servlet.FilterChain;  
  7. import javax.servlet.FilterConfig;  
  8. import javax.servlet.ServletException;  
  9. import javax.servlet.ServletRequest;  
  10. import javax.servlet.ServletResponse;  
  11.   
  12. public class CharsetEncodingFilter implements Filter {  
  13.     private String endcoding;  
  14.       
  15.     @Override  
  16.     public void destroy() {  
  17.         // TODO Auto-generated method stub  
  18.     }  
  19.   
  20.     @Override  
  21.     public void doFilter(ServletRequest request, ServletResponse response,  
  22.             FilterChain chain) throws IOException, ServletException {  
  23.         request.setCharacterEncoding(endcoding);  
  24.           
  25.         //繼續執行  
  26.         chain.doFilter(request, response);    
  27.     }  
  28.   
  29.     @Override  
  30.     public void init(FilterConfig filterConfig) throws ServletException {  
  31.         this.endcoding = filterConfig.getInitParameter("encoding");  
  32.     }  
  33. }  

Filter雖不是一個Servlet,但它須要在web.xml文件中配置以後才能使用,具體解釋看代碼中的註釋,以下: 編程

[html]   view plain copy print ?
  1. <filter>        
  2.     <filter-name>CharsetEncodingFilter</filter-name>  
  3.     <filter-class>com.snail.drp.util.filter.CharsetEncodingFilter</filter-class>  
  4.     <!--在Filter初始化時,設置編碼格式  -->  
  5.     <init-param>  
  6.         <param-name>encoding</param-name>  
  7.         <param-value>GB18030</param-value>  
  8.     </init-param>  
  9. </filter>  
  10. <!-- 設置Filter範圍,指對Post請求起做用 -->  
  11. <filter-mapping>  
  12.     <filter-name>CharsetEncodingFilter</filter-name>  
  13.     <url-pattern>*.jsp</url-pattern>  
  14. </filter-mapping>  
  15. <filter-mapping>  
  16.     <filter-name>CharsetEncodingFilter</filter-name>  
  17.     <url-pattern>/servlet/*</url-pattern>  
  18. </filter-mapping>  
[html]   view plain copy print ?
  1. <filter>        
  2.     <filter-name>CharsetEncodingFilter</filter-name>  
  3.     <filter-class>com.snail.drp.util.filter.CharsetEncodingFilter</filter-class>  
  4.     <!--在Filter初始化時,設置編碼格式  -->  
  5.     <init-param>  
  6.         <param-name>encoding</param-name>  
  7.         <param-value>GB18030</param-value>  
  8.     </init-param>  
  9. </filter>  
  10. <!-- 設置Filter範圍,指對Post請求起做用 -->  
  11. <filter-mapping>  
  12.     <filter-name>CharsetEncodingFilter</filter-name>  
  13.     <url-pattern>*.jsp</url-pattern>  
  14. </filter-mapping>  
  15. <filter-mapping>  
  16.     <filter-name>CharsetEncodingFilter</filter-name>  
  17.     <url-pattern>/servlet/*</url-pattern>  
  18. </filter-mapping>  

Filter是職責鏈模式的經典應用,從上面示例代碼能夠看出,實現了Filter接口的doFilter方法主要用於截獲Request對象,把截獲的請求處理後(設置字符集),調用FilterChain 接口的chain.doFilter(request,response)方法,把處理權傳遞給下一個filter。 安全

 

其中,FilterChain維護了一個鏈表,鏈表中存放着配置對象的鏈條,每次用戶調用 一次chain.doFilter(request, response),鏈表就去取下一個配置對象,再經過配置對象 獲得下一個filter,而後調用該filter,接着在filter裏寫的邏輯就被執行了。 架構

 

http://blog.csdn.net/stubbornpotatoes/article/details/7347663 app

相關文章
相關標籤/搜索