通过HttpServletRequestWrapper消除乱码

来源:互联网 发布:公安现场绘图软件 编辑:程序博客网 时间:2024/04/27 15:03

原文连接  http://www.java3z.com/cwbwebhome/article/article5/51046.html?id=2387

应用一:解决tomcat下中文乱码问题

在tomcat下,我们通常这样来解决中文乱码问题:

 

过滤器代码:

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按照已经设置的字符编码来进行字符输出。

 

通过过滤器,我们可以保证在Servlet或JSP执行之前就设置好了请求和响应的字符编码。

 

但是这样并不能完全解决中文乱码问题:

对于post请求,无论是“获取参数环节”还是“输出环节"都是没问题的;

对于get请求,"输出环节"没有问题,但是"获取参数环节"依然出现中文乱码,所以在输出时直接将乱码输出了。

 

原因是post请求和get请求存放参数位置是不同的:

post方式参数存放在请求数据包的消息体中。get方式参数存放在请求数据包的请求行的URI字段中,以?开始以param=value&parame2=value2的形式附加在URI字段之后。而request.setCharacterEncoding(charset); 只对消息体中的数据起作用,对于URI字段中的参数不起作用,我们通常通过下面的代码来完成编码转换:

 

String paramValue = request.getParameter("paramName");paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset);

 

但是每次进行这样的转换实在是很麻烦,有没有统一的解决方案呢?

 

解决方案1: 在tomcat_home\conf\server.xml 中的Connector元素中设置URIEncoding属性为合适的字符编码

 

    <Connector port="8080" protocol="HTTP/1.1"                connectionTimeout="20000"                redirectPort="8443"                URIEncoding="UTF-8"     />

 

这样做的缺点是,同一个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方法来获取参数,就已经完成了字符编码的转换过程,我们就不需要在每次获取参数时来进行字符编码转换了。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 转转上买二手电脑被骗了怎么办 如果电脑买贵了怎么办 电脑配置低玩lol卡怎么办 电视打开显示无信号怎么办 电脑卡怎么办换个驱动 刚开始开淘宝店没人买怎么办 公司有人带自己电脑办公怎么办 组装电脑连不上网怎么办 显卡玩不起吃鸡怎么办 u盘内存是假的怎么办 新买的电脑应该怎么办 海尔一体机电脑开不开机怎么办 苹果笔记本系统坏了怎么办 苹果笔记本电脑电池坏了怎么办 苹果笔记本电脑屏幕坏了怎么办 平板开关键坏了怎么办 平板电脑电池坏了怎么办 平板电脑充电口坏了怎么办 平板电脑系统坏了怎么办 平板电脑充电器坏了怎么办 平板电脑触摸屏坏了怎么办 平板电脑关不了机怎么办 平板电脑触摸屏没反应怎么办 平板电脑声音太小怎么办 平板电脑频碎了怎么办? 淘宝直播展示频道排后怎么办 网店头像改不了怎么办 被骗了7500追不回来怎么办 steam中国版原来的游戏怎么办 老公买驾照被骗妻子应该怎么办 被淘密码骗了怎么办 逛街手机没电了怎么办 电脑登入密码忘了怎么办 晚上睡不好觉经常做梦怎么办 开淘宝店开始零销量怎么办 淘宝店开直通车后销量怎么办 淘宝直播一开始直播没人该怎么办 淘宝店铺访客数据下滑怎么办 2个ctrl键都失灵怎么办 淘宝上搜索不到很久以前订单怎么办 关键词找不到了是不是被降权怎么办