過濾器就是一種在請求目標資源的中間組件,比喻把污水轉換成純淨水中間需要一個污水淨化設備,那麼這個設備就好比一個過濾器。那麼我用圖來表示過濾器(可以有多個過濾器)運行的過程
Filter接口包含三個方法分別是init、doFilter、 destroy下面先逐個介紹。
這個方法主要來完成初始化過濾器,容器調用這個方法的時候,向過濾器傳遞FilterConfig對象,FilterConfig的用法和ServletConfig相似,利用FilterConfig對象可以得到ServletContext對象,以及可以得到部署描述符中過濾器初始化的參數。
該方法和Servlet中的service相似,當客戶端請求目標資源的時候,容器就會調用與這個目標資源相關聯的過濾器的doFilter方法,在這個方法中可以對請求和響應進行處理,實現過濾器的特定功能,在處理完成之後調用chain.doFilter把請求傳給下一個過濾器(目標資源)
當過濾器生命結束的時候,容器就會調用該方法來釋放過濾器的資源
過濾器是通過<filter>和<filter-mapping>元素來完成的。
<filter>元素的屬性,<filter-name>來為過濾器指定一個名字,<filter-class>元素用於指定過濾器完整的限定類名,<init-param>用來為過濾器指定初始化參數,他下面有2個屬性,一個是<param-name>參數名稱,另一個是<param-value>參數值。
<filter-mapping>下面有3個主要的屬性,<filter-name>用來指定過濾已經在容器聲明的過濾器名稱,<url-pattren>和<servlet-name>這兩個任選其中一個,<url-pattren>表示當請求這樣的url時候過濾器被調用,<servlet-name>表示當這個Servlet被調用時候過濾器被調用(可以有多個Servlet)。
基本知識准備完畢了,現在我們一起開始進行實踐。
由於Web容器默認的編碼方式是ISO-8859-1,在Servlet/Jsp程序中,通過請求的對象的getParameter()方法得到的字符串是以ISO-8859-1轉換而來(有人說我在jsp程序已經設置了UTF-8為什麼還出現這種情況呢,那是由於web容器再次對請求的數據進行一次轉換,所以後來得到字符串就是ISO-8859-1編碼的),這就是導致亂碼的原因。如下圖
那麼找到根源以後問題就比較好解決了,核心代碼如下
public class EncodingFilter implements Filter { protected String encoding=null; class myRequestWrapper extends HttpServletRequestWrapper{ public myRequestWrapper(HttpServletRequest request) { super(request); } public String getParameter(String param) { String value=null; try{ //post提交 super.setCharacterEncoding(encoding); value=super.getParameter(param); if(super.getMethod().equalsIgnoreCase("GET"))//get提交 { if(value!=null) { value=new String(value.getBytes("iso8859-1"), encoding); } } } catch(UnsupportedEncodingException e){ e.printStackTrace(); } return value; } } public void init(FilterConfig filterConfig) throws ServletException { this.encoding=filterConfig.getInitParameter("encoding");//從web容器來獲取過濾器初始化參數 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //避免響應出現亂碼情況 response.setCharacterEncoding("text/html;charset="+this.encoding); //把過濾器給下一個過濾器或者資源處理器 chain.doFilter(new myRequestWrapper((HttpServletRequest)request), response); } public void destroy() { this.encoding=null; } }
對過濾器進行配置
<filter> <filter-name>encoding</filter-name> <filter-class>com.lp.filters.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <servlet-name>LoginServlet</servlet-name> <!-- <url-pattern>/LoginServlet</url-pattern> --> </filter-mapping>
ok上面的過濾器就完成了,大家自行測試。