來自:http://www.javaeye.com/topic/483158java
應用一:解決tomcat下中文亂碼問題(先來個簡單的) web
在tomcat下,咱們一般這樣來解決中文亂碼問題:tomcat
過濾器代碼:app
package filter; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import wrapper.GetHttpServletRequestWrapper; public class ContentTypeFilter implements Filter { private String charset = "UTF-8"; private FilterConfig config; public void destroy() { System.out.println(config.getFilterName()+"被銷燬"); charset = null; config = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //設置請求響應字符編碼 request.setCharacterEncoding(charset); response.setCharacterEncoding(charset); HttpServletRequest req = (HttpServletRequest)request; System.out.println("----請求被"+config.getFilterName()+"過濾"); //執行下一個過濾器(若是有的話,不然執行目標servlet) chain.doFilter(req, response); System.out.println("----響應被"+config.getFilterName()+"過濾"); } public void init(FilterConfig config) throws ServletException { this.config = config; String charset = config.getServletContext().getInitParameter("charset"); if( charset != null && charset.trim().length() != 0) { this.charset = charset; } } }
web.xml中過濾器配置:jsp
<context-param> <param-name>charset</param-name> <param-value>UTF-8</param-value> </context-param> <filter> <filter-name>ContentTypeFilter</filter-name> <filter-class>filter.ContentTypeFilter</filter-class> </filter> <filter-mapping> <filter-name>ContentTypeFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
request.setCharacterEncoding(charset); 必須寫在第一次使用request.getParameter()以前,這樣才能保證參數是按照已經設置的字符編碼來獲取。
response.setCharacterEncoding(charset);必須寫在PrintWriter out = request.getWriter()以前,這樣才能保證out按照已經設置的字符編碼來進行字符輸出。post
經過過濾器,咱們能夠保證在Servlet或JSP執行以前就設置好了請求和響應的字符編碼。this
可是這樣並不能徹底解決中文亂碼問題:編碼
對於post請求,不管是「獲取參數環節」仍是「輸出環節"都是沒問題的;url
對於get請求,"輸出環節"沒有問題,可是"獲取參數環節"依然出現中文亂碼,因此在輸出時直接將亂碼輸出了。spa
緣由是post請求和get請求存放參數位置是不一樣的:
post方式參數存放在請求數據包的消息體中。get方式參數存放在請求數據包的請求行的URI字段中,以?開始以param=value¶me2=value2的形式附加在URI字段以後。而request.setCharacterEncoding(charset); 只對消息體中的數據起做用,對於URI字段中的參數不起做用,咱們一般經過下面的代碼來完成編碼轉換:
可是每次進行這樣的轉換實在是很麻煩,有沒有統一的解決方案呢?
解決方案1: 在tomcat_home\conf\server.xml 中的Connector元素中設置URIEncoding屬性爲合適的字符編碼
這樣作的缺點是,同一個tomcat下的其餘應用也將受到影響。而其每次部署時都須要類修改配置也很麻煩。
解決方案2:自定義請求包裝器包裝請求,將字符編碼轉換的工做添加到getParameter()方法中
package wrapper; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper { private String charset = "UTF-8"; public GetHttpServletRequestWrapper(HttpServletRequest request) { super(request); } /** * 得到被裝飾對象的引用和採用的字符編碼 * @param request * @param charset */ public GetHttpServletRequestWrapper(HttpServletRequest request, String charset) { super(request); this.charset = charset; } /** * 實際上就是調用被包裝的請求對象的getParameter方法得到參數,而後再進行編碼轉換 */ public String getParameter(String name) { String value = super.getParameter(name); value = value == null ? null : convert(value); return value; } public String convert(String target) { System.out.println("編碼轉換以前:" + target); try { return new String(target.trim().getBytes("ISO-8859-1"), charset); } catch (UnsupportedEncodingException e) { return target; } } } 修改過濾器的doFilter方法 代碼如
下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //設置請求響應字符編碼 request.setCharacterEncoding(charset); response.setCharacterEncoding(charset); //新增長的代碼 HttpServletRequest req = (HttpServletRequest)request; if(req.getMethod().equalsIgnoreCase("get")) { req = new GetHttpServletRequestWrapper(req,charset); } System.out.println("----請求被"+config.getFilterName()+"過濾"); //傳遞給目標servlet或jsp的實際上時包裝器對象的引用,而不是原始的HttpServletRequest對象 chain.doFilter(req, response); System.out.println("----響應被"+config.getFilterName()+"過濾"); }
這樣一來,在servlet中調用包裝器的getParameters方法來獲取參數,就已經完成了字符編碼的轉換過程,咱們就不須要在每次獲取參數時來進行字符編碼轉換了。