HttpServletRequestWrapper相關(guān)
應(yīng)用一:解決tomcat下中文亂碼問(wèn)題(先來(lái)個(gè)簡(jiǎn)單的)
在tomcat下,我們通常這樣來(lái)解決中文亂碼問(wèn)題:
過(guò)濾器代碼:
- 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()+"被銷(xiāo)毀");
- charset = null;
- config = null;
- }
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- //設(shè)置請(qǐng)求響應(yīng)字符編碼
- request.setCharacterEncoding(charset);
- response.setCharacterEncoding(charset);
- HttpServletRequest req = (HttpServletRequest)request;
- System.out.println("----請(qǐng)求被"+config.getFilterName()+"過(guò)濾");
- //執(zhí)行下一個(gè)過(guò)濾器(如果有的話,否則執(zhí)行目標(biāo)servlet)
- chain.doFilter(req, response);
- System.out.println("----響應(yīng)被"+config.getFilterName()+"過(guò)濾");
- }
- 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中過(guò)濾器配置
<!--將采用的字符編碼配置成應(yīng)用初始化參數(shù)而不是過(guò)濾器私有的初始化參數(shù)是因?yàn)樵贘SP和其他地方也可能需要使用-->
<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>
equest.setCharacterEncoding(charset); 必須寫(xiě)在第一次使用request.getParameter()之前,這樣才能保證參數(shù)是按照已經(jīng)設(shè)置的字符編碼來(lái)獲取。
response.setCharacterEncoding(charset);必須寫(xiě)在PrintWriter out = request.getWriter()之前,這樣才能保證out按照已經(jīng)設(shè)置的字符編碼來(lái)進(jìn)行字符輸出。
通過(guò)過(guò)濾器,我們可以保證在Servlet或JSP執(zhí)行之前就設(shè)置好了請(qǐng)求和響應(yīng)的字符編碼。
但是這樣并不能完全解決中文亂碼問(wèn)題:
對(duì)于post請(qǐng)求,無(wú)論是“獲取參數(shù)環(huán)節(jié)”還是“輸出環(huán)節(jié)"都是沒(méi)問(wèn)題的;
對(duì)于get請(qǐng)求,"輸出環(huán)節(jié)"沒(méi)有問(wèn)題,但是"獲取參數(shù)環(huán)節(jié)"依然出現(xiàn)中文亂碼,所以在輸出時(shí)直接將亂碼輸出了。
原因是post請(qǐng)求和get請(qǐng)求存放參數(shù)位置是不同的:
post方式參數(shù)存放在請(qǐng)求數(shù)據(jù)包的消息體中。 get方式參數(shù)存放在請(qǐng)求數(shù)據(jù)包的請(qǐng)求行的URI字段中,以?開(kāi)始以param=value¶me2=value2的形式附加在URI字段之后。而request.setCharacterEncoding(charset); 只對(duì)消息體中的數(shù)據(jù)起作用,對(duì)于URI字段中的參數(shù)不起作用,我們通常通過(guò)下面的代碼來(lái)完成編碼轉(zhuǎn)換:
String paramValue = request.getParameter("paramName");
paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset);
但是每次進(jìn)行這樣的轉(zhuǎn)換實(shí)在是很麻煩,有沒(méi)有統(tǒng)一的解決方案呢?
解決方案1: 在tomcat_home"conf"server.xml 中的Connector元素中設(shè)置URIEncoding屬性為合適的字符編碼
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
/>
這樣做的缺點(diǎn)是,同一個(gè)tomcat下的其他應(yīng)用也將受到影響。而其每次部署時(shí)都需要類(lèi)修改配置也很麻煩。
解決方案2:自定義請(qǐng)求包裝器包裝請(qǐng)求,將字符編碼轉(zhuǎn)換的工作添加到getParameter()方法中















































修改過(guò)濾器的doFilter方法 代碼如下:


















這樣一來(lái),在servlet中調(diào)用包裝器的getParameters方法來(lái)獲取參數(shù),就已經(jīng)完成了字符編碼的轉(zhuǎn)換過(guò)程,我們就不需要在每次獲取參數(shù)時(shí)來(lái)進(jìn)行字符編碼轉(zhuǎn)換了。
總結(jié):自己寫(xiě)類(lèi)繼承HttpServletRequestWrapper,HttpServletRequestWrapper實(shí)現(xiàn)了HttpServletRequest接口。看tomcat的源代碼可以發(fā)現(xiàn),ServletRequest作為一個(gè)Component ,ServletRequestWrapper作為一個(gè)比較標(biāo)準(zhǔn)的Decorator ,實(shí)現(xiàn)ServletRequest接口并把ServletRequest當(dāng)作成員變量,其他繼承Decorator 的類(lèi)(比如本例中的GetHttpServletRequestWrapper )就可以很好的操控ServletRequest及其子類(lèi)(比如本例中的HttpServletRequest),HttpServletRequest的很多方法就可以根據(jù)我們的需求做改變,比如設(shè)置字符,去掉空格。
參考:
http://www.javaeye.com/topic/483158
http://fishhappy365.javaeye.com/blog/484185
http://www.javaeye.com/topic/220230
posted on 2009-11-22 22:30 yuxh 閱讀(7205) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): j2ee 、設(shè)計(jì)模式