在企業開發中,最常見的是javaweb項目,有web項目就免不了和後台打交道,比如我從jsp頁面發送新增請求到後台,後台可能是servlet、struts2、springmvc等,這時就存在一個問題,在發送的參數值中如果包含中文經常到了後台你發現會是亂碼,當然你可以在後台拿到值後對值進行重新編碼,但是如果每次都要進行重新編碼,會很麻煩,這裡介紹一中簡單的方式,希望可以對你有用。
filter
filter叫做過濾器,是java servlet中的技術,通過filter我們可以對要訪問的web服務器的資源進行過濾,如下圖,從網上找的
可以看到要加了filter之後,要訪問web資源必須通過過濾器,如果沒有過濾器那麼我們可以直接訪問web資源,這就是過濾器的作用,即可以控制對資源的訪問;例如可以監控用戶訪問的url,可以禁止未登錄的用戶訪問,當然還有一個重點,那就是可以過濾字符集。好了進入正題
Filter開發
要開發filter有兩個步驟
1、編寫java類實現javax.servlet.Filter接口
2、注冊filter
編寫filter實現類
一、filter接口有三個方法:init、destory、doFilter
init
在filter創建時候執行,filter的創建有web服務器負責,在啟動web服務器時會創建filter,這時便會執行filter的init方法,因為filter只會被創建一次,故init方法只會被調用一次,在此方法中可以獲得通過FilterConfig獲得注冊時的初始化參數,提供了如下方法:
String getFilterName():得到filter的名稱。
String getInitParameter(String name): 返回在部署描述中指定名稱的初始化參數的值。如果不存在返回null.
Enumeration getInitParameterNames():返回過濾器的所有初始化參數的名字的枚舉集合。
public ServletContext getServletContext():返回Servlet上下文對象的引用。
destory
web服務器調用destory方法銷毀filter,在filter的生命周期中此方法只執行一次,用戶釋放filter中使用的資源,如數據庫連接等。
doFilter
此方法是整個filter的關鍵,我們要做的工作主要在此方法中完成,此方法提供三個參數:ServletRequest req, ServletResponse resp,
FilterChain chain ;chain參數是filter鏈,如果我們想讓請求繼續往下執行必須調用chain.doFilter方法,這樣請求才會向下傳遞,我們可以根據自己的業務選擇在何時調用chain.doFilter方法。
二、注冊filter
所謂注冊filter就是讓web服務器知道filter,讓filter起作用,需要再web.xml中進行注冊,具體的注冊的方式可以參考下邊的例子。
字符過濾器
filter代碼如下:
1 package com.cn.imooc.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 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 public class SetCharacterEncodingFilter implements Filter { 15 16 //存儲編碼格式信息 17 private String encode = null; 18 @Override 19 public void destroy() { 20 // TODO Auto-generated method stub 21 22 } 23 24 @Override 25 public void doFilter(ServletRequest req, ServletResponse resp, 26 FilterChain chain) throws IOException, ServletException { 27 // TODO Auto-generated method stub 28 29 //轉換 30 HttpServletRequest request = (HttpServletRequest)req; 31 HttpServletResponse response = (HttpServletResponse)resp; 32 33 /* 34 * 判斷在web.xml文件中是否配置了編碼格式的信息 35 * 如果為空,則設置編碼格式為配置文件中的編碼格式 36 * 否則編碼格式設置為utf-8
37 */ 38 if(this.encode != null && !this.encode.equals("")){ 39 request.setCharacterEncoding(this.encode); 40 response.setCharacterEncoding(this.encode); 41 }else{ 42 request.setCharacterEncoding("utf-8"); 43 response.setCharacterEncoding("utf-8"); 44 } 45 46 /* 47 * 使用doFilter方法調用鏈中的下一個過濾器或目標資源(servlet或JSP頁面)。 48 * chain.doFilter處理過濾器的其余部分(如果有的話),最終處理請求的servlet或JSP頁面。 49 */ 50 chain.doFilter(request, response); 51 52 } 53 54 @Override 55 public void init(FilterConfig arg0) throws ServletException { 56 // TODO Auto-generated method stub 57 58 this.encode=arg0.getInitParameter("encode"); 59 System.out.println("this.encode:"+encode); 60 } 61 62 }
在init方法中獲得配置的初始化參數“encode”,把請求強轉為httpSerevletRequest和HttpServletResponse,然後設置編碼,最後調用chain.doFilter(request,response)方法,這樣便實現了對編碼的過濾。
注冊filter如下,在web.xml中:
1 <!-- 過濾器配置信息 --> 2 <filter> 3 <filter-name>SetCharacterEncodingFilter</filter-name> 4 <!-- 過濾器設置編碼文件 --> 5 <filter-class>com.cn.imooc.filter.SetCharacterEncodingFilter</filter-class> 6 <init-param> 7 <!-- init-param元素定義了過濾器的初始化參數--> 8 <description>給參數和值設置名稱和編碼類型</description> 9 <param-name>encode</param-name> 10 <param-value>utf-8</param-value> 11 </init-param> 12 </filter> 13 <filter-mapping> 14 <!-- filter-mapping告訴容器所有與模式向匹配的請求都應該允許通過訪問控制過濾器。 15 所有以.action結尾的訪問都先通過過濾器文件過濾 --> 16 <filter-name>SetCharacterEncodingFilter</filter-name> 17 <url-pattern>*.action</url-pattern> 18 </filter-mapping>
在注冊filter的時候我們配置了初始化參數,設為了utf-8,在攔截的url中設置了,攔截所有的以action為結尾的url請求。
通過以上的代碼便可以統一設置請求的編碼
有不對之處歡迎之處,謝謝!