• 2007年07月17日

    中文乱码 - [技术同盟]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://butoo.blogbus.com/logs/6803281.html

    有必要把前几天出现乱码问题的几种解决方案做个总结。。
    在页面传递中文字符的时候,经常出现乱码问题。以下几种解决方法是我常用的:
    1. 在jsp页面开头写入request.setCharacterEncoding("GBK") 。
    说明:这种方法时灵时不灵,什么原因不太清楚。。
    2. 写一个简单的转码函数,例如以下的一个转化函数:
    <%!
    public String codeToString(String str) {
     String s = str;
     try {
      byte temp[] = s.getBytes("GBK");
      s = new String(temp);
      return s;
     } catch (Exception e) {
      out.println(e);
     }
    }
    %>
    懒的话简单的写成str=new String(str.getBytes("8859_1"),"GBK")) 。
    说明:当有很多乱码的地方要转码时,这种方法太笨。
    3. 可以在HTTP Connector里面设置属性URIEncoding的值为"GBK",默认的是"ISO-8859-1"。这种方法使用与页面之间传递中文参数出现乱码的情况。例如:
    <Connector
            port="8181" redirectPort="8443" minSpareThreads="25" connectionTimeout="60000"
            connectionLinger="-1" serverSoTimeout="0" maxSpareThreads="75"
            maxThreads="150" maxHttpHeaderSize="8192" tcpNoDelay="true" URIEncoding="GBK">
    </Connector>
    可以参考http://tomcat.jaxwiki.com/config/http.html,里面有对HTTP Connector的一些介绍。
    说明:个人觉得Apache的Tomcat很脆弱,比如在URIEncoding="GBK"的前面如果有两个空格的话,那么tomcat就启动不了。汗。。。
    4. 用上面讲的三种方法都不能彻底解决乱码问题,有时候页面之间传递乱码能解决,但是提交到数据库中的乱码不能解决。不如自己来定义servlet和JSP页面的过滤器filter,用以过滤页面传递信息的编码方式。基本步骤如下:
    首先建立一个实现filter接口的类,如下:
    package filters;

    import java.io.IOException;
    import javax.servlet.*;

    public class SetCharacterEncodingFilter
         implements Filter {

         protected String encoding;
         protected FilterConfig filterConfig;
         protected boolean ignore;

     public SetCharacterEncodingFilter(){
             encoding = null;
             filterConfig = null;
             ignore = true;
         }

         public void destroy(){//终止调用
             encoding = null;
             filterConfig = null;
         }

        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException{//设置过滤行为
            if(ignore || request.getCharacterEncoding() == null){
                String encoding = selectEncoding(request);
                if(encoding != null)
                    request.setCharacterEncoding(encoding);
                else
                    request.setCharacterEncoding("gb2312");
            }
            chain.doFilter(request, response);
        }

        public void init(FilterConfig filterConfig)
            throws ServletException{//初始化参数
            this.filterConfig = filterConfig;
            encoding = filterConfig.getInitParameter("encoding");
            String value = filterConfig.getInitParameter("ignore");
            if(value == null)
                ignore = true;
            else
            if(value.equalsIgnoreCase("true"))
                ignore = true;
            else
            if(value.equalsIgnoreCase("yes"))
                ignore = true;
            else
                ignore = false;
        }

        protected String selectEncoding(ServletRequest request){
            return encoding;
        }
    }
    将SetCharacterEncodingFilter.class放到\classes\filters目录下。
    第二步就是在\WEB.xml中注册过滤器,其中要用到两个过滤器元素filter和filter-mapping:
    <!-- filter元素向系统注册一个过滤对象SetCharacterEncodingFilter开始  -->
    <filter>
      <filter-name>Set Character Encoding</filter-name>
      <filter-class>filters.SetCharacterEncodingFilter</filter-class>
      <init-param>
       <param-name>encoding</param-name>
       <param-value>GBK</param-value>
      </init-param> 
    </filter>
    <!-- filter元素向系统注册一个过滤对象SetCharacterEncodingFilter结束  -->
     
    <!-- filter-mapping元素指定SetCharacterEncodingFilter所应用的URL开始 -->
     <filter-mapping>
        <filter-name>Set Character Encoding</filter-name>
          <url-pattern>/*</url-pattern>
       </filter-mapping>
    <!-- filter-mapping元素指定SetCharacterEncodingFilter所应用的URL结束 -->

    说明:个人觉得filter真的是个好东东,可以用来解决很多很多问题,如提供访问决策、封装公共行为等等。
    5. 有时候出现乱码也有可能是连接驱动问题,换高些版本的驱动。
    说明:要是再不行,建议给数据库打补丁吧。。


    历史上的今天:

    1/5/07 到 21/5/07 2007年07月17日
    21/4/07 到 30/4/07 2007年07月17日

    收藏到:Del.icio.us




    评论

  • 狂强,牛人呀,过来采采