来自:http://www.javaeye.com/topic/483158

应用一:解决tomcat下中文乱码问题(先来个简单的)

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

过滤器代码:

  1. package filter;
  2. import java.io.*;
  3. import javax.servlet.*;
  4. import javax.servlet.http.*;
  5. import wrapper.GetHttpServletRequestWrapper;
  6. public class ContentTypeFilter implements Filter {
  7. private String charset = "UTF-8";
  8. private FilterConfig config;
  9. public void destroy() {
  10. System.out.println(config.getFilterName()+"被销毁");
  11. charset = null;
  12. config = null;
  13. }
  14. public void doFilter(ServletRequest request, ServletResponse response,
  15. FilterChain chain) throws IOException, ServletException {
  16. //设置请求响应字符编码
  17. request.setCharacterEncoding(charset);
  18. response.setCharacterEncoding(charset);
  19. HttpServletRequest req = (HttpServletRequest)request;
  20. System.out.println("----请求被"+config.getFilterName()+"过滤");
  21. //执行下一个过滤器(如果有的话,否则执行目标servlet)
  22. chain.doFilter(req, response);
  23. System.out.println("----响应被"+config.getFilterName()+"过滤");
  24. }
  25. public void init(FilterConfig config) throws ServletException {
  26. this.config = config;
  27. String charset = config.getServletContext().getInitParameter("charset");
  28. if( charset != null && charset.trim().length() != 0)
  29. {
  30. this.charset = charset;
  31. }
  32. }
  33. }

web.xml中过滤器配置:

  1. <!--将采用的字符编码配置成应用初始化参数而不是过滤器私有的初始化参数是因为在JSP和其他地方也可能需要使用-->
  2. <context-param>
  3. <param-name>charset</param-name>
  4. <param-value>UTF-8</param-value>
  5. </context-param>
  6. <filter>
  7. <filter-name>ContentTypeFilter</filter-name>
  8. <filter-class>filter.ContentTypeFilter</filter-class>
  9. </filter>
  10. <filter-mapping>
  11. <filter-name>ContentTypeFilter</filter-name>
  12. <url-pattern>/*</url-pattern>
  13. </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字段中的参数不起作用,我们通常通过下面的代码来完成编码转换:

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

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

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

  1. <Connector port="8080" protocol="HTTP/1.1"
  2. connectionTimeout="20000"
  3. redirectPort="8443"
  4. URIEncoding="UTF-8"
  5. />

这样做的缺点是,同一个tomcat下的其他应用也将受到影响。而其每次部署时都需要类修改配置也很麻烦。

解决方案2:自定义请求包装器包装请求,将字符编码转换的工作添加到getParameter()方法中

  1. package wrapper;
  2. import java.io.UnsupportedEncodingException;
  3. import java.net.URLDecoder;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletRequestWrapper;
  6. public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {
  7. private String charset = "UTF-8";
  8. public GetHttpServletRequestWrapper(HttpServletRequest request) {
  9. super(request);
  10. }
  11. /**
  12. * 获得被装饰对象的引用和采用的字符编码
  13. * @param request
  14. * @param charset
  15. */
  16. public GetHttpServletRequestWrapper(HttpServletRequest request,
  17. String charset) {
  18. super(request);
  19. this.charset = charset;
  20. }
  21. /**
  22. * 实际上就是调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换
  23. */
  24. public String getParameter(String name) {
  25. String value = super.getParameter(name);
  26. value = value == null ? null : convert(value);
  27. return value;
  28. }
  29. public String convert(String target) {
  30. System.out.println("编码转换之前:" + target);
  31. try {
  32. return new String(target.trim().getBytes("ISO-8859-1"), charset);
  33. } catch (UnsupportedEncodingException e) {
  34. return target;
  35. }
  36. }
  37. }

修改过滤器的doFilter方法 代码如下:

  1. public void doFilter(ServletRequest request, ServletResponse response,
  2. FilterChain chain) throws IOException, ServletException {
  3. //设置请求响应字符编码
  4. request.setCharacterEncoding(charset);
  5. response.setCharacterEncoding(charset);
  6. //新增加的代码
  7. HttpServletRequest req = (HttpServletRequest)request;
  8. if(req.getMethod().equalsIgnoreCase("get"))
  9. {
  10. req = new GetHttpServletRequestWrapper(req,charset);
  11. }
  12. System.out.println("----请求被"+config.getFilterName()+"过滤");
  13. //传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象
  14. chain.doFilter(req, response);
  15. System.out.println("----响应被"+config.getFilterName()+"过滤");
  16. }

这样一来,在servlet中调用包装器的getParameters方法来获取参数,就已经完成了字符编码的转换过程,我们就不需要在每次获取参数时来进行字符编码转换了。

 
http://825635381.iteye.com/blog/2178986

最新文章

  1. Linux安装mariadb二进制版本
  2. c# Newtonsoft.Json序列化和反序列 js解析
  3. ssd硬盘u盘装win7扩展文件时0x80070570错误
  4. Like ruby of SBM Crusher zip to dict
  5. linux 多核
  6. iOS开发之自定义控制器切换
  7. 将MFC Grid control封装为DLL的做法及其在DLL中的使用方法
  8. 算法题丨Remove Duplicates from Sorted Array II
  9. 【译】索引进阶(八):SQL SERVER唯一索引
  10. JavaScript之事件的绑定与移除
  11. 涨姿势:Java 分业务、分级别实现自定义日志打印
  12. conda管理python包
  13. sql server获取插入记录后的ID
  14. JavaScript(js)处理的HTML事件、键盘事件、鼠标事件
  15. 以下web.xml片断( )正确地声明servlet 上下文参数。
  16. Java基础知识陷阱(三)
  17. MlskincolorButton使用方法
  18. MSSQL 基础知识001
  19. 【Python之路】第十八篇--MySQL(一)
  20. 大话CNN经典模型:LeNet

热门文章

  1. win7 虚拟机 ios开发环境搭建
  2. ADO.NET 1创建连接、执行命令
  3. Can&#39;t call commit when autocommit=true(转)
  4. 图示CCScrollView的相关概念
  5. Pro Android 4 第五章 理解Intent
  6. axure网格设置
  7. 1.1.2-学习Opencv与MFC混合编程之---画图工具 画直线 画圆 画矩形
  8. wift - 使用UIScreen类获取屏幕大小尺寸
  9. Servlet的学习之web路径问题
  10. Codeforces Round #197 (Div. 2) D. Xenia and Bit Operations