1、尽量使用统一的编码,如果你是重头开发一个系统,特别是Java开发的,推荐从页面到数据库再到配置文件都使用UTF-8进行编码,安全第一。

2、采用三种方式
1)入门方法,在所有的servlet和jsp中堆设定用的代码。
2)中级方法,对web伺服器进行配置。
3)高级方法,编写filter过滤器,对“POST”和“GET”独立过滤处理。
上面的注意对post和get的分别处理

3、数据库的乱码
a.设置数据库的编码
b.创建connection时候,在url中传递编码
jdbc:mysql://localhost:3306/hibernateTest?useUnicode=true&characterEncoding=GBK
c.当传递的数据和数据库不一致,只能重新new string














【参考】http://www.javaeye.com/topic/31742
乱码对于使用非英语文字程序员基本上是一直缠绕在身边的麻烦事,这个谁也避免不了。下面是我解决乱码时候的一点小经验。欢迎指正
 
一、避免乱码的一些注意点:
1.尽量使用统一的编码,如果你是重头开发一个系统,特别是Java开发的,推荐从页面到数据库再到配置文件都使用UTF-8进行编码,安全第一。
2.SetCharacterEncodingFilter的使用,这个东西不是万能的,但是没有它就会很麻烦,如果是基于Servlet开发的东西,能用的就给它用上,省心。不过有一个注意的地方,这个Filter只是对POST请求有效,GET一律忽略,不信你可以debug一下,看看它怎么做的,至于为什么不过滤get请求,好象是它对GET请求是无能为力的。
3.就如上面所说,GET请求有问题,尽量使用POST请求,这个也是Web开发的一个基本要领:
Web Health Warning:Put All Destructive Actions Behind a POST method(from Agile Web Development with Rails)
有点扯远了,不过少用GET,是会有回报滴。
4.JavaScript和Ajax乱码的避免,注意JavaScript默认是ISO8859的编码,避免JS/AJAX乱码和GET一样,不要在URL里面使用中文,实在避免不了,就只能在生成链接的时候转码,绝对不能想当然的认为SetCharacterEncodingFilter会帮你做什么事情。
5.尽早统一开发环境,早点模拟真实环境测试,这个好像也有跑题的嫌疑,但凡软件开发都是这么干的,但仍然值得注意。我这出现过一次状况,程序是在Win下编译的,拿去Linux上测试没问题,等实际部署的时候代码是在Linux下编译,结果乱码,秋后算帐总觉得有点晚。

二、乱码发生的情况和应对措施
1.开发环境乱码
      由于Java默认使用UTF-8编码,而且网上很多人都建议Struts开发的时候应尽量选用UTF-8做为默认编码,而非GBK。IDE使 用Eclipse,在第一次使用Eclipse的时候应将default text editor改为UTF-8编码,免得日后后悔再改就惨了,我本次开发的时候就忽视了这一点,刚开始没注意,结果到快交工时乱码问题无法解决,导致将所有 的文件全部修改一遍,呜……
      自打使用Ubuntu,我就开心的笑阿,再也不用为搞这些乱码问题而烦恼^^(Ubuntu公益广告)
2.POST请求的过滤
      这个是最基本的了,每个Servlet系统基本都会用到这个东西。不过只对POST请求有效,这个挺关键的。
      使用SetCharacterEncodingFilter,这个很基础的一套过滤器,将所有来自页面的POST请求全部过滤为UTF-8编码。
3. JSP ,HTML页面乱码
     将JSP页面全部改为charset=UTF-8,这样可以保证与后台交互的时候都是UTF-8编码,一般应用做了以上工作就基本可以应付了。
4.资源文件中汉字转化UTF-8字符问题
      国际化问题,在使用资源文件的时候,由于中文在properties文件中无法被程序所识别,需要将其进行转码,我在资源文件下面制作了一个很简单的 bat文件,每次修改资源文件的时候都是在一个临时文件中修改,然后执行这个bat文件,将其转化并保存为所需要的资源文件,这个动作挺烦的,也有项目组 成员使用一些插件,但是那些东西都是直接写UTF-8码的,有时候反倒不方便,不过以后任务量巨大的时候可能会考虑使用。Bat文件内容:   set path=%path%;%JAVA_HOME%/bin/,native2ascii -encoding UTF-8 ApplicationResources_bk.txt > ApplicationResources_zh.properties

     PS:上面的方法好老了,实际操作起来相当麻烦,现在基本都是使用Eclipse插件,Eclipse3.1时使用PropertyEditor,但是这 个项目看上去好像停摆了,到Eclipse3.2时改用了ResourseBundle,相当的强劲的一个插件,推荐使用。
5. GET请求乱码
      如果在本项目中采用了get方式提交请求并附加参数,结果导致编码乱码,原因是Tomcat默认请求编码是ISO8859,需要在Tomcat的配置文件 server.xml添加一个参数,URIEncoding=”UTF-8”,这样请求中附件的参数就会以UTF-8来进行编码。
6.Ajax请求乱码
    使用Ajax,JS也是默认使用ISO8859编码,所以在进行请求时遇到中文参数需要进行编码,如:var url = "GetSelectListAction.do?queryData=subTrade" + "&queryId=" + encodeURI(obj.value) + "&r=" + Math.random();  
    这里有两个地方需要注意:第一个地方是encodeURI(),方法,可以将参数进行转码,默认是转化为UTF-8,如果需要转为其他码制,需要在方法中添加第二个参数。
     第二个地方是Math.random(),由于Ajax有缓存机制,在接受请求的时候第一时间先判断该请求的地址是否被访问过,如果被访问过则 直接使用缓存中的内容返回,这个东西很讨厌,客户在访问过一次出错后以后每次出现的都是这个错误,所以在请求中给其增加一个时间戳,只要可以随机生成一个 不同的字串就可以,保证Ajax每次都去访问服务器。
7. GET方法的另一个乱码问题
      在项目即将交工的时候突然又出现乱码问题,发现对于超长的汉字做为参数传递仍然会出现乱码问题,解决方法是采用java.net.URLEncoder的 Encode方法强制转码,缺点是会使JSP页面代码相当的长,但是目前还没有其他好的解决办法,我想最好的办法就是不用中文做为参数传递 :P,写法如:<a href="TestAction.do?name=<%= java.net.URLEncoder.encode("你好","UTF-8")%>

8.乱码仍然是偶们的心病,一直牵动着大家的心,最近一位朋友说连接MSSQL数据库有乱码,使用了很多办法,都没解决,后来重新下了个新的驱动搞定……
数据库乱码其实也很讨厌的,一般来说驱动问题比较常见,所以一旦碰到比较难缠的乱码可以先考虑下换换驱动。也有如MySQL这种,直接连接的时候就需要显示进行编码转化的,这个就要不同情况区别对待了。

//2007年11月30日添加
9.WebService乱码,由于对WebService不怎么熟悉,使用的是Weblogic提供的WebService支持,乱码再次出现搞得手忙脚乱,而且无从下手,在自己系统上跑都没有问题,结果跑到服务器上就全乱套,又无法调试,愁人。
    反复尝试的过程就不说了,绝对比普通的Web开发麻烦的多。最终解决方法:
    A.为WebService服务也加上一个filter,WebService也是走HTTP协议的,这个东西同样有用,先得加上。
    B.修改服务器上的环境变量,LANG=zh_CN.UTF-8,改成这个是为什么我仍然说的不是很清楚,不过当时开发人员就是在Win下开发的,我在自己的Ubuntu上测试没问题,拿到Redhat服务器上就不行,因为服务器上默认的是LANG=en_US.UTF-8,这个明显是不支持汉字的。
    经过这两个步骤WebService乱码总算得到抑制,它主要的麻烦在于所有与协议有关的东西都被Weblogic包办,里面做什么事情我们不好控制,所以只能采取这种比较笨的办法,虽然解燃煤之急但无法寻根溯源的搞定它,说不定哪天又会出来搞鬼。果然又一次出现乱码问题,经过比较环境变量发现服务器上的LC_CTYPE被修改了,所以强制改成LC_CTYPE=zh_CN。修改环境变量的方法不到万不得已不推荐使用。



【参考】Java开发,表单提交中发生中文乱码的问题。

Web开发的中文问题一直困惑大家,尤其是对于初上手者。这次有机会彻底解决研究了一下中文乱码的原因和解决方案,做个总结。
为什么会有中文乱码?
因为在默认情况下,HTTP的包都是以“8859_1”来编码的(没办法,谁叫这些标准都是老美定的)。“8859_1”是西文编码方式,对于英文字母没有任何问题,但是对于中文就不行了。所以,如果不做任何设定,直接将中文用“8859_1”来编码传递,那结果必然是乱码。
解决思路是什么?
好在老美还是有国际化眼光的,HTTP包的编码方式可以由用户指定。因此,只要事先指定好用相对应的编码方式来对传递内容(比如表单提交的中文等)进行编码,就可以顺利解决乱码的问题。
两个基本概念
在进入具体的解决方法之前,首先要对两个基本概念作一下解释。对于由表单提交的内容,HTTP有两种传递方式,分别是“GET”方式和“POST”方式。
“GET”方式就是将各参数直接通过HTTP的包头(head)来传递,简而言之就是直接通过我们所熟悉的网址(URL)来传递,所以我们经常能看到的在一个网址后面跟着许多复杂的由“?”和“&”构成的字符串,其实这就是需要传递的参数了。
“POST”方式则是将所需传递的参数包在HTTP的正文(body)中来传递。因此通过“POST”方式来进行传递,在浏览器的网址上面什么都看不见。
因此,相比较而言,“POST”隐蔽性较好;而“GET”方式使用起来比较容易,直接写URL就可以了。
综上所述,不难发现,解决中文乱码问题实际上就变为对这两种HTTP传递的编码方式进行适当的设定。当然,从解决问题的难易以及对系统架构的完美性角度着手,又分为以下三个层次:
1)入门方法,在所有的servlet和jsp中堆设定用的代码。
2)中级方法,对web伺服器进行配置。
3)高级方法,编写filter过滤器,对“POST”和“GET”独立过滤处理。
下面就具体描述各解决方法:
1)入门方法,在所有的servlet和jsp中“堆”写设定用的代码。
所谓入门方法,那就是现实十分简单,当然效果也是很好的。只是必须在每个相应的文件中写相同的设定代码,代码的重复性就比较大。
由前面所述,由于“POST”和“GET”方式的不同,因此对应着两种的设定方式也不同。
“POST”的情况下,如果服务器端脚本是一个servlet,那只要在doPost()方法里面插入一句

request.setCharacterEncode("GB2312");

需要注意的是,这句设定必须在所有从request对象做提取操作之前执行,如果类似于request.getParameter()的操作在前,那么系统将使用默认的“8859_1”编码方式,而忽略后面的设定代码。
如果服务器端是一个jsp脚本,那只要在该脚本的jsp申明部分做好设定即可:

<%@ page language="java" contentType="text/html; charset=gb2312" pageEncoding="gb2312"%>

如果是“GET”方式,也就是想通过URL来传递中文的话,稍微要麻烦些,首先因为浏览器地址栏是不支持中文的,也就是如果直接将中文放置在超级连接里面是无效的。因此需要在发送端对中文内容进行编码,比如:

URLEncoder.encoder("http://localhost/submit?name=张三","UTF-8");

“UTF-8”表示用这种编码方式对原字符串进行编码,编码好之后看到的结果是

http://localhost/submit?name=%D5%C5%C8%FD

所以我们经常看到在浏览器里面有众多的类似与“%D5%C5%C8%FD”这样的字符串,就是表明被UTF-8编码过了。由于UTF-8是跨各种平台的通用编码方式,因此比较常用于各种语言文字的传输载体。
相对应的,在接受方需要进行反向的解码即可,代码如下:

new String( request.getParameter("name").getBytes("8859_1"), "gb2312" );

这里可能会有一些疑问,为什么用“8859_1”来解码。事实上,我在第一次尝试的时候也曾使用“UTF-8”来尝试解码,结果出现乱码失败。究其原因,尽管“张三”被编码成了“%D5%C5%C8%FD”来传输,但是在传输过程中,“%D5%C5%C8%FD”仍旧需要由“8859_1”来编码打包成HTTP,因此,在接收端,自然先需要由“8859_1”来还原到“%D5%C5%C8%FD”的“UTF-8”格式,然后再由“UTF-8”还原到“GB2312”。
所以这样也不难理解为什么所谓“浏览器地址栏是不支持中文”,不能直接用中文而要用“UTF-8”来通过“8859_1”来打包了,原因就是“%D5%C5%C8%FD”这串类似于密码般的字符串本身就是西文字符,用“8859_1”编解码没有任何问题。而中文由于是2byte一个汉字,直接用西文方式来编解码自然就会出现问题。这也就是为什么称“UTF-8”为“跨各种平台的通用编码方式”了。
背景小资料:
由于“UTF-8”是通用编码方式,因此所有的语言格式均可以转换为“UTF-8”,在日益国际的今天,多语言的系统要求越来越多,因此强烈建议使用“UTF-8”来做为系统统一的编解码方式,从而彻底解决中文乱码的问题。
“UTF-8”为了能做到兼容所有语言的编解码,因此每一个字符均用2个byte来编码。这样就造成了存西文字符时需要多一倍的空间。这也算是为了通用而付出的代价了。
2)中级方法,对web伺服器进行配置
可想而知,相对于“堆”写大量代码,配置一下web伺服器config文件来解决中文乱码问题就显得优雅许多。但是由于各种web伺服器的情况不同,其配置方法也不尽相同。因此,其兼容性是个比较大的问题。
这里列举一下,如何通过修改Tomcat的conf配置文件来解决中文乱码的问题。
找到Tomcat的配置文件server.xml中的Connector这一行,为其添加一个如下的属性

tomcat4 中 get 与 post 的编码是一样的,所以只要在过滤器中通过 request.setCharacterEncoding 设定一次就可以解决 get 与 post 的问题。
然而,在 tomcat5 中,get 与 post 的处理是分开进行的,对get的处理通过 前面的URIEncoding进行处理,对post的内容依然通过 request.setCharacterEncoding 处理,为了保持兼容,就有了这个设定(useBodyEncodingForURI="true" 使用与 Body 一样的编码来处理 URI, 这个设定是为了与 tomcat4保持兼容)。




3)高级方法,编写filter过滤器,对“POST”和“GET”独立过滤处理。
高级方法,顾名思义,就是可以脱离于任何平台,同时又免去冗余的队旗代码工作的解决方案——编写过滤器,Filter。
首先编写一个过滤器SetCharacterEncodingFilter

public class SetCharacterEncodingFilter implements Filter {
/**
        * The default character encoding to set for requests that pass through
        * this filter.
        */
protected String encoding = null;
/**
        * The filter configuration object we are associated with.  If this value
        * is null, this filter instance is not currently configured.
        */
   protected FilterConfig filterConfig = null;
   /**
       * Should a character encoding specified by the client be ignored?
       */    
protected boolean ignore = true;
 // --------------------------------------------------------- Public Methods
   /**
    * Take this filter out of service.
    */
   public void destroy() {
       this.encoding = null;
       this.filterConfig = null;
   }
/**
    * Select and set (if specified) the character encoding to be used to
    * interpret request parameters for this request.
    *
    * @param request The servlet request we are processing
    * @param result The servlet response we are creating
    * @param chain The filter chain we are processing
    *
    * @exception IOException if an input/output error occurs
    * @exception ServletException if a servlet error occurs
    */
   public void doFilter(ServletRequest request, ServletResponse response,
                        FilterChain chain)
   throws IOException, ServletException {
 // Conditionally select and set the character encoding to be used
       if (ignore || (request.getCharacterEncoding() == null)) {
           String encoding = selectEncoding(request);
           if(encoding != null){
               HttpServletRequest httpServletRequest = (HttpServletRequest) request;
               if(httpServletRequest.getMethod().toLowerCase().equals("post")){
   //如果是POST方法
                   request.setCharacterEncoding(encoding);
               }
               else{
                 //如果是GET方法
                   //非常抱歉,我还有没有找到很好的对应get方法的代码
                   //一旦完成了这部分代码,马上添加在这里。
                   //!·#¥%……—*()——+|
               }
           }
       }
 // Pass control on to the next filter
       chain.doFilter(request, response);
   }
   /**
    * Place this filter into service.
    *
    * @param filterConfig The filter configuration object
    */
   public void init(FilterConfig filterConfig) throws ServletException {
   this.filterConfig = filterConfig;
       this.encoding = filterConfig.getInitParameter("encoding");
       String value = filterConfig.getInitParameter("ignore");
       if (value == null)
           this.ignore = true;
       else if (value.equalsIgnoreCase("true"))
           this.ignore = true;
       else if (value.equalsIgnoreCase("yes"))
           this.ignore = true;
       else
           this.ignore = false;
   }
 // ------------------------------------------------------ Protected Methods
   /**
    * Select an appropriate character encoding to be used, based on the
    * characteristics of the current request and/or filter initialization
    * parameters.  If no character encoding should be set, return
    * <code>null</code>.
    * <p>
    * The default implementation unconditionally returns the value configured
    * by the <strong>encoding</strong> initialization parameter for this
    * filter.
    *
    * @param request The servlet request we are processing
    */
   protected String selectEncoding(ServletRequest request) {
       return (this.encoding);
   }
}

编写完过滤器以后,需要对其进行部署,也就是在web.xml中做个配置:
在<display-name>标签之后,添加:

   <filter>
       <filter-name>Set Character Encoding</filter-name>
       <filter-class>com.zavax.utility.filters.SetCharacterEncodingFilter</filter-class>
           <init-param>
               <param-name>encoding</param-name>
               <param-value>UTF8</param-value>
           </init-param>
           <init-param>
               <param-name>ignore</param-name>
               <param-value>true</param-value>
           </init-param>
       </filter>
   <filter-mapping>
       <filter-name>Set Character Encoding</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>