`
yanghuidang
  • 浏览: 959048 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

java汉字乱码解决办法

阅读更多
自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首 先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程 中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果 必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 <%@   page   contentType= "text/html;charset=GBK "%> 或 <%@   page   contentType= "text/html;charset=gb2312 "%> 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char
从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char
从java程序到数据库   char—> byte

从文件到java程序   byte-> char
从java程序到文件   char-> byte

从流到java程序   byte-> char
从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码
JSP 获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页 面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( "GBK ")或request.setCharacterEncoding( "gb2312 ")。
如果在JSP将变量输出到页面时出现了乱码,可以 通过设置response.setContentType( "text/html;charset=GBK ")或response.setContentType( "text/html;charset=gb2312 ")解决。
如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:
web.xml:

<filter>
<filter-name> CharacterEncodingFilter </filter-name>
<filter-class> net.vschool.web.CharacterEncodingFilter </filter-class>
<init-param>
<param-name> encoding </param-name>
<param-value> GBK </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> CharacterEncodingFilter </filter-name>
<url-pattern> /* </url-pattern>
</filter-mapping>

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter  
{

protected   String   encoding   =   null;  

public   void   init(FilterConfig   filterConfig)   throws   ServletException  
{
this.encoding   =   filterConfig.getInitParameter( "encoding ");
}

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException  
{
request.setCharacterEncoding(encoding);
response.setContentType( "text/html;charset= "+encoding);
chain.doFilter(request,   response);
}

}


2、Java与数据库之间的乱码
大 部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据 库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的 mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true& characterEncoding=GBK。

3、Java与文件/流之间的乱码
Java读写文件最常用的类是 FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream 和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和 FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。 在这种情况下,建议使用FileReader和FileWriter的父 类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类 型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。  

4、其他
上 面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你 必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组 件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题 困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。 smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认 的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性 charset和setCharset(String)方法,将upload()方法中提取参数语句:
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1   );
改成了
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1,   charset   );
终于解决了这个乱码问题。
 
自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首 先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程 中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果 必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 <%@   page   contentType= "text/html;charset=GBK "%> 或 <%@   page   contentType= "text/html;charset=gb2312 "%> 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char
从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char
从java程序到数据库   char—> byte

从文件到java程序   byte-> char
从java程序到文件   char-> byte

从流到java程序   byte-> char
从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码
JSP 获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页 面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( "GBK ")或request.setCharacterEncoding( "gb2312 ")。
如果在JSP将变量输出到页面时出现了乱码,可以 通过设置response.setContentType( "text/html;charset=GBK ")或response.setContentType( "text/html;charset=gb2312 ")解决。
如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:
web.xml:

<filter>
<filter-name> CharacterEncodingFilter </filter-name>
<filter-class> net.vschool.web.CharacterEncodingFilter </filter-class>
<init-param>
<param-name> encoding </param-name>
<param-value> GBK </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> CharacterEncodingFilter </filter-name>
<url-pattern> /* </url-pattern>
</filter-mapping>

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter  
{

protected   String   encoding   =   null;  

public   void   init(FilterConfig   filterConfig)   throws   ServletException  
{
this.encoding   =   filterConfig.getInitParameter( "encoding ");
}

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException  
{
request.setCharacterEncoding(encoding);
response.setContentType( "text/html;charset= "+encoding);
chain.doFilter(request,   response);
}

}


2、Java与数据库之间的乱码
大 部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据 库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的 mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true& characterEncoding=GBK。

3、Java与文件/流之间的乱码
Java读写文件最常用的类是 FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream 和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和 FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。 在这种情况下,建议使用FileReader和FileWriter的父 类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类 型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。  

4、其他
上 面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你 必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组 件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题 困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。 smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认 的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性 charset和setCharset(String)方法,将upload()方法中提取参数语句:
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1   );
改成了
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1,   charset   );
终于解决了这个乱码问题。
 
自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首 先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程 中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果 必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 <%@   page   contentType= "text/html;charset=GBK "%> 或 <%@   page   contentType= "text/html;charset=gb2312 "%> 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char
从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char
从java程序到数据库   char—> byte

从文件到java程序   byte-> char
从java程序到文件   char-> byte

从流到java程序   byte-> char
从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码
JSP 获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页 面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( "GBK ")或request.setCharacterEncoding( "gb2312 ")。
如果在JSP将变量输出到页面时出现了乱码,可以 通过设置response.setContentType( "text/html;charset=GBK ")或response.setContentType( "text/html;charset=gb2312 ")解决。
如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:
web.xml:

<filter>
<filter-name> CharacterEncodingFilter </filter-name>
<filter-class> net.vschool.web.CharacterEncodingFilter </filter-class>
<init-param>
<param-name> encoding </param-name>
<param-value> GBK </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> CharacterEncodingFilter </filter-name>
<url-pattern> /* </url-pattern>
</filter-mapping>

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter  
{

protected   String   encoding   =   null;  

public   void   init(FilterConfig   filterConfig)   throws   ServletException  
{
this.encoding   =   filterConfig.getInitParameter( "encoding ");
}

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException  
{
request.setCharacterEncoding(encoding);
response.setContentType( "text/html;charset= "+encoding);
chain.doFilter(request,   response);
}

}


2、Java与数据库之间的乱码
大 部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据 库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的 mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true& characterEncoding=GBK。

3、Java与文件/流之间的乱码
Java读写文件最常用的类是 FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream 和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和 FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。 在这种情况下,建议使用FileReader和FileWriter的父 类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类 型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。  

4、其他
上 面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你 必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组 件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题 困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。 smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认 的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性 charset和setCharset(String)方法,将upload()方法中提取参数语句:
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1   );
改成了
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1,   charset   );
终于解决了这个乱码问题。

 

自从接触Java和JSP以来,就不断与Java的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,Java和JSP文件本身编译时产生的乱码问题和Java程序于其他媒介交互产生的乱码问题。

首 先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,如果Java和JSP编译成class文件过程 中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果 必须写的话,尽量手动带参数-ecoding   GBK或-ecoding   gb2312编译;对于JSP,在文件头加上 <%@   page   contentType= "text/html;charset=GBK "%> 或 <%@   page   contentType= "text/html;charset=gb2312 "%> 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即Java程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的,Java程序与这些媒介交互时就会发生字符(char)与字节(byte)之间的转换,具体情况如下:

从页面form提交数据到java程序   byte-> char
从java程序到页面显示   char—> byte

从数据库到java程序   byte—> char
从java程序到数据库   char—> byte

从文件到java程序   byte-> char
从java程序到文件   char-> byte

从流到java程序   byte-> char
从java程序到流   char-> byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了Java程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述(Java或JSP自身产生的乱码请参看第一部分)。

1、JSP与页面参数之间的乱码
JSP 获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页 面获取参数之前,强制指定request获取参数的编码方式:request.setCharacterEncoding( "GBK ")或request.setCharacterEncoding( "gb2312 ")。
如果在JSP将变量输出到页面时出现了乱码,可以 通过设置response.setContentType( "text/html;charset=GBK ")或response.setContentType( "text/html;charset=gb2312 ")解决。
如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤器的在web.xml中的典型配置和主要代码如下:
web.xml:

<filter>
<filter-name> CharacterEncodingFilter </filter-name>
<filter-class> net.vschool.web.CharacterEncodingFilter </filter-class>
<init-param>
<param-name> encoding </param-name>
<param-value> GBK </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> CharacterEncodingFilter </filter-name>
<url-pattern> /* </url-pattern>
</filter-mapping>

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter  
{

protected   String   encoding   =   null;  

public   void   init(FilterConfig   filterConfig)   throws   ServletException  
{
this.encoding   =   filterConfig.getInitParameter( "encoding ");
}

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException  
{
request.setCharacterEncoding(encoding);
response.setContentType( "text/html;charset= "+encoding);
chain.doFilter(request,   response);
}

}


2、Java与数据库之间的乱码
大 部分数据库都支持以unicode编码方式,所以解决Java与数据库之间的乱码问题比较明智的方式是直接使用unicode编码与数据库交互。很多数据 库驱动自动支持unicode,如Microsoft的SQLServer驱动。其他大部分数据库驱动,可以在驱动的url参数中指定,如如mm的 mysql驱动:jdbc:mysql://localhost/WEBCLDB?useUnicode=true& characterEncoding=GBK。

3、Java与文件/流之间的乱码
Java读写文件最常用的类是 FileInputStream/FileOutputStream和FileReader/FileWriter。其中FileInputStream 和FileOutputStream是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的FileReader和 FileWriter,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。 在这种情况下,建议使用FileReader和FileWriter的父 类:InputStreamReader/OutputStreamWriter,它们也是基于字符的,但在构造函数中可以指定编码类 型:InputStreamReader(InputStream   in,   Charset   cs)   和OutputStreamWriter(OutputStream   out,   Charset   cs)。  

4、其他
上 面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决Java乱码问题的关键在于在字节与字符的转换过程中,你 必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用Resin服务器,使用smartUpload组 件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在Linux中把Resin设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题 困扰了我们很久,后来我们分析smartUpload组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。 smartUpload组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在smartUpload将字节流转换成字符串时采用了系统默认 的编码,而将Resin设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了smartUpload的源文件,增加了一个属性 charset和setCharset(String)方法,将upload()方法中提取参数语句:
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1   );
改成了
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1,   charset   );
终于解决了这个乱码问题。

自从接触 Java JSP 以来,就不断与 Java 的中文乱码问题打交道,现在终于得到了彻底的解决,现将我们的解决心得与大家共享。

一、 Java 中文问题的由来

Java
的内核和 class 文件是基于 unicode 的,这使 Java 程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面, Java JSP 文件本身编译时产生的乱码问题和 Java 程序于其他媒介交互产生的乱码问题。

首先 Java (包括 JSP )源文件中很可能包含有中文,而 Java JSP 源文件的保存方式是基于字节流的,如果 Java JSP 编译成 class 文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。基于这种乱码,建议在 Java 文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写的话,尽量手动带参数- ecoding   GBK 或- ecoding   gb2312 编译;对于 JSP ,在文件头加上 <%@   page   contentType= "text/html;charset=GBK "%> <%@   page   contentType= "text/html;charset=gb2312 "%> 基本上就能解决这类乱码问题。

本文要重点讨论的是第二类乱码,即 Java 程序与其他存储媒介交互时产生的乱码。很多存储媒介,如数据库,文件,流等的存储方式都是基于字节流的, Java 程序与这些媒介交互时就会发生字符 (char) 与字节 (byte) 之间的转换,具体情况如下:

从页面 form 提交数据到 java 程序   byte > char
java 程序到页面显示   char—> byte

从数据库到 java 程序   byte—> char
java 程序到数据库   char—> byte

从文件到 java 程序   byte > char
java 程序到文件   char > byte

从流到 java 程序   byte > char
java 程序到流   char > byte

如果在以上转换过程中使用的编码方式与字节原有的编码不一致,很可能就会出现乱码。

二、解决方法

前面已经提到了 Java 程序与其他媒介交互时字符和字节的转换过程,如果这些转换过程中容易产生乱码。解决这些乱码问题的关键在于确保转换时使用的编码方式与字节原有的编码方式保持一致,下面分别论述( Java JSP 自身产生的乱码请参看第一部分)。

1
JSP 与页面参数之间的乱码
JSP
获取页面参数时一般采用系统默认的编码方式,如果页面参数的编码类型和系统默认的编码类型不一致,很可能就会出现乱码。解决这类乱码问题的基本方法是在页面获取参数之前,强制指定 request 获取参数的编码方式: request.setCharacterEncoding( "GBK ") request.setCharacterEncoding( "gb2312 ")
如果在 JSP 将变量输出到页面时出现了乱码,可以通过设置 response.setContentType( "text/html;charset=GBK ") response.setContentType( "text/html;charset=gb2312 ") 解决。
如果不想在每个文件里都写这样两句话,更简洁的办法是使用 Servlet 规范中的过虑器指定编码,过滤器的在 web.xml 中的典型配置和主要代码如下:
web.xml:

<filter>
<filter-name> CharacterEncodingFilter </filter-name>
<filter-class> net.vschool.web.CharacterEncodingFilter </filter-class>
<init-param>
<param-name> encoding </param-name>
<param-value> GBK </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> CharacterEncodingFilter </filter-name>
<url-pattern> /* </url-pattern>
</filter-mapping>

CharacterEncodingFilter.java:

public   class   CharacterEncodingFilter   implements   Filter  
{

protected   String   encoding   =   null;  

public   void   init(FilterConfig   filterConfig)   throws   ServletException  
{
this.encoding   =   filterConfig.getInitParameter( "encoding ");
}

public   void   doFilter(ServletRequest   request,   ServletResponse   response,   FilterChain   chain)   throws   IOException,   ServletException  
{
request.setCharacterEncoding(encoding);
response.setContentType( "text/html;charset= "+encoding);
chain.doFilter(request,   response);
}

}


2
Java 与数据库之间的乱码
大部分数据库都支持以 unicode 编码方式,所以解决 Java 与数据库之间的乱码问题比较明智的方式是直接使用 unicode 编码与数据库交互。很多数据库驱动自动支持 unicode ,如 Microsoft SQLServer 驱动。其他大部分数据库驱动,可以在驱动的 url 参数中指定,如如 mm mysql 驱动: jdbc:mysql://localhost/WEBCLDB?useUnicode=true&characterEncoding=GBK

3
Java 与文件 / 流之间的乱码
Java
读写文件最常用的类是 FileInputStream/FileOutputStream FileReader/FileWriter 。其中 FileInputStream FileOutputStream 是基于字节流的,常用于读写二进制文件。读写字符文件建议使用基于字符的 FileReader FileWriter ,省去了字节与字符之间的转换。但这两个类的构造函数默认使用系统的编码方式,如果文件内容与系统编码方式不一致,可能会出现乱码。在这种情况下,建议使用 FileReader FileWriter 的父类: InputStreamReader/OutputStreamWriter ,它们也是基于字符的,但在构造函数中可以指定编码类型: InputStreamReader(InputStream   in,   Charset   cs)   OutputStreamWriter(OutputStream   out,   Charset   cs)  

4
、其他
上面提到的方法应该能解决大部分乱码问题,如果在其他地方还出现乱码,可能需要手动修改代码。解决 Java 乱码问题的关键在于在字节与字符的转换过程中,你必须知道原来字节或转换后的字节的编码方式,转换时采用的编码必须与这个编码方式保持一致。我们以前使用 Resin 服务器,使用 smartUpload 组件上传文件,上传文件同时传递的中文参数获取没有乱码问题。当在 Linux 中把 Resin 设置成服务后,上传文件同时的中文参数获取出现了乱码。这个问题困扰了我们很久,后来我们分析 smartUpload 组件的源文件,因为文件上传采用的是字节流的方式,里面包含的参数名称和值也是字节流的方式传递的。 smartUpload 组件读取字节流后再将参数名称和值从字节流中解析出来,问题就出现在 smartUpload 将字节流转换成字符串时采用了系统默认的编码,而将 Resin 设置成服务后,系统默认的编码可能发生了改变,因此出现了乱码。后来,我们更改了 smartUpload 的源文件,增加了一个属性 charset setCharset(String) 方法,将 upload() 方法中提取参数语句:
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1   );
改成了
String   value   =   new   String(m_binArray,   m_startData,   (m_endData   -   m_startData)   +   1,   charset   );
终于解决了这个乱码问题。

0
0
分享到:
评论
1 楼 liuzejian4 2011-03-30  
你为啥吧相同的东西贴了几遍呀

相关推荐

    彻底解决中文乱码的问题

    在IT行业中,尤其是在Java编程领域,中文乱码...在提供的压缩包文件“中文乱码的问题决绝.doc”中,可能详细列举了各种情况下的乱码问题以及对应的解决办法,包括实例代码和步骤,建议查阅该文档以获取更具体的指导。

    Java Web程序开发中字符乱码的原因与解决办法.pdf

    Java Web程序开发中字符乱码的原因与解决办法 字符乱码问题是Java Web程序开发过程中经常遇到的一个问题,它会对用户界面的友好性以及信息的准确传达造成很大的影响。为了解决这个问题,我们首先要了解字符集和字符...

    csv文件中文会乱码工具

    excel打开csv文件中文乱码问题,将乱码文件拖到此工具就可完成转码,正常显示中文。

    Java 编程技术中汉字问题的分析及解决

    解决办法是在编译时指定编码,例如`javac -encoding GBK`。 字节码到虚拟机再到操作系统的阶段,Java运行环境(JRE)的国际版支持非英文字符。但是,如果用户没有安装国际版,或者系统配置不当,可能会导致汉字显示...

    jsp 中文乱码 原因及彻底解决办法

    【JSP 中文乱码的原因及解决方法】 在开发基于Java的JSP应用程序时,遇到中文乱码问题是很常见的困扰。这是因为Java的核心和class文件基于Unicode编码,这为跨平台提供了便利,但也引入了处理中文字符时可能出现的...

    Docker容器 日志中文乱码问题解决办法

    Docker容器 日志中文乱码问题解决办法 1. 找到dockerfile文件, 如 /use/local/src/Docker/Dockerfile 2. 编辑Dockerfile 添加 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 3. 生成新的...

    Java get 提交乱码处理方法

    解决办法  1、在后台获取时采用  String b = new String(request.getParameter("name").getBytes("iso-8859-1"));  2、 String a = new String(request.getParameter("name").getBytes("iso-8859-1"),"GBK")...

    Ireport中文不显示以及乱码十几种解决方案

    以上就是针对IReport中文不显示及乱码问题的十几种解决方案,每种情况都有其特定的解决办法。在尝试时,请根据自己的具体情况进行操作,相信总有一种方法能帮你解决问题。如果问题依然存在,建议查阅IReport的官方...

    中文乱码解决方法(已验证).docx

    解决办法是在Servlet中,对POST请求的请求体使用正确的字符集解码,如`new String(request.getParameter("param").getBytes("ISO-8859-1"), "UTF-8")`。 2. GET请求乱码:GET请求的参数会附加在URL上,浏览器按照URL...

    J2EE平台下的乱码问题分析及解决

    此外,解决汉字乱码问题还需要注意如下几点心得: - 对于不同版本的Java,它们的默认编码可能不同,需要根据实际的Java版本进行相应的编码设置。 - 在进行国际化软件开发时,应该避免在系统中使用默认编码,而应该...

    PHP中文乱码解决方案

    汉字乱码真是一个悲催的事情,JAVA讨厌汉字,PHP也不喜欢汉字;  Java乱码最终使用了spring给出的过滤器来过滤,处处过滤,其实影响了速度,不过没有办法,汉字就是W国首先不考虑的事情;  想不到PHP也是乱码处...

    EBS xml publisher中文乱码问题及解决办法

    以下是对这个问题的详细分析和解决办法。 一、字符集问题 1. 输出 XML 时,确保在 PL/SQL 代码中指定正确的字符集。例如,可以在输出 XML 头信息时设置编码为 UTF-8: ```sql output(‘”1.0″ encoding=”UTF-8”...

    MyEclipse中properties文件支持中文的解决办法

    标题“MyEclipse中properties文件支持中文的解决办法”所指向的核心问题是在MyEclipse集成开发环境中,使用.properties文件进行国际化时遇到中文显示异常的情况。解决这个问题通常需要改变文件的编码方式或者利用...

    Servlet 中文乱码问题

    针对Servlet中的响应(response)乱码问题,常见的解决办法是设置响应头来指定编码。例如,`response.setContentType("text/html;charset=UTF-8")`告诉浏览器内容类型为HTML,并使用UTF-8编码。而`response.set...

    Java Web中请求消息和响应消息中文乱码问题的研究与对策.pdf

    解决办法是手动使用ISO-8859-1重新编码接收到的参数,然后用UTF-8解码,例如`new String(name.getBytes("ISO8859-1"), "UTF-8")`。 对于响应消息的中文乱码,主要是响应体的编码设置。在Servlet中,可以使用...

    解决JSON.stringify()自动将中文转译成unicode的问题

    查找资料后发现,与标准的JSON.stringify()不同,IE8内置的JSON.stringify()会自动将编码从utf-8转为unicode编码,导致出现这种类似于乱码的情况。 解决方法分为两种,第一种是后台接收到数据之后,将该数据再进行一...

    java存取oracle中的COLB类型数据.pdf

    3. 刚插入的记录就 select for update,会出现“违反读取顺序”错误,解决办法是将自动提交功能置为 false,即不允许自动提交,然后 commit 它,再 select,就可以了。 在读取 COLB 数据时,需要将其转换为 Unicode...

    linux jfreechat 终极解决

    5. **阅读解决办法**:"linux jfreechat.txt"文件可能包含了更详细的解决步骤或额外的提示。打开这个文本文件,按照其中的指导进行操作。 在尝试上述步骤之前,确保你的Java环境已经正确配置,并且JFreeChart库已...

    Java字符转换[参照].pdf

    解决办法是使用`native2ascii`工具将汉字转换为`\uXXXX`格式。例如:`native2ascii -encoding GBK inputfile outputfile`。 XML文件的读取需要注意文件头部的`&lt;?xml version="1.0" encoding="gb2312"?&gt;`声明,确保...

Global site tag (gtag.js) - Google Analytics