自从接触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 );
终于解决了这个乱码问题。
分享到:
相关推荐
在IT行业中,尤其是在Java编程领域,中文乱码...在提供的压缩包文件“中文乱码的问题决绝.doc”中,可能详细列举了各种情况下的乱码问题以及对应的解决办法,包括实例代码和步骤,建议查阅该文档以获取更具体的指导。
Java Web程序开发中字符乱码的原因与解决办法 字符乱码问题是Java Web程序开发过程中经常遇到的一个问题,它会对用户界面的友好性以及信息的准确传达造成很大的影响。为了解决这个问题,我们首先要了解字符集和字符...
excel打开csv文件中文乱码问题,将乱码文件拖到此工具就可完成转码,正常显示中文。
解决办法是在编译时指定编码,例如`javac -encoding GBK`。 字节码到虚拟机再到操作系统的阶段,Java运行环境(JRE)的国际版支持非英文字符。但是,如果用户没有安装国际版,或者系统配置不当,可能会导致汉字显示...
【JSP 中文乱码的原因及解决方法】 在开发基于Java的JSP应用程序时,遇到中文乱码问题是很常见的困扰。这是因为Java的核心和class文件基于Unicode编码,这为跨平台提供了便利,但也引入了处理中文字符时可能出现的...
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. 生成新的...
解决办法 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的官方...
解决办法是在Servlet中,对POST请求的请求体使用正确的字符集解码,如`new String(request.getParameter("param").getBytes("ISO-8859-1"), "UTF-8")`。 2. GET请求乱码:GET请求的参数会附加在URL上,浏览器按照URL...
此外,解决汉字乱码问题还需要注意如下几点心得: - 对于不同版本的Java,它们的默认编码可能不同,需要根据实际的Java版本进行相应的编码设置。 - 在进行国际化软件开发时,应该避免在系统中使用默认编码,而应该...
汉字乱码真是一个悲催的事情,JAVA讨厌汉字,PHP也不喜欢汉字; Java乱码最终使用了spring给出的过滤器来过滤,处处过滤,其实影响了速度,不过没有办法,汉字就是W国首先不考虑的事情; 想不到PHP也是乱码处...
以下是对这个问题的详细分析和解决办法。 一、字符集问题 1. 输出 XML 时,确保在 PL/SQL 代码中指定正确的字符集。例如,可以在输出 XML 头信息时设置编码为 UTF-8: ```sql output(‘”1.0″ encoding=”UTF-8”...
标题“MyEclipse中properties文件支持中文的解决办法”所指向的核心问题是在MyEclipse集成开发环境中,使用.properties文件进行国际化时遇到中文显示异常的情况。解决这个问题通常需要改变文件的编码方式或者利用...
针对Servlet中的响应(response)乱码问题,常见的解决办法是设置响应头来指定编码。例如,`response.setContentType("text/html;charset=UTF-8")`告诉浏览器内容类型为HTML,并使用UTF-8编码。而`response.set...
解决办法是手动使用ISO-8859-1重新编码接收到的参数,然后用UTF-8解码,例如`new String(name.getBytes("ISO8859-1"), "UTF-8")`。 对于响应消息的中文乱码,主要是响应体的编码设置。在Servlet中,可以使用...
查找资料后发现,与标准的JSON.stringify()不同,IE8内置的JSON.stringify()会自动将编码从utf-8转为unicode编码,导致出现这种类似于乱码的情况。 解决方法分为两种,第一种是后台接收到数据之后,将该数据再进行一...
3. 刚插入的记录就 select for update,会出现“违反读取顺序”错误,解决办法是将自动提交功能置为 false,即不允许自动提交,然后 commit 它,再 select,就可以了。 在读取 COLB 数据时,需要将其转换为 Unicode...
5. **阅读解决办法**:"linux jfreechat.txt"文件可能包含了更详细的解决步骤或额外的提示。打开这个文本文件,按照其中的指导进行操作。 在尝试上述步骤之前,确保你的Java环境已经正确配置,并且JFreeChart库已...
解决办法是使用`native2ascii`工具将汉字转换为`\uXXXX`格式。例如:`native2ascii -encoding GBK inputfile outputfile`。 XML文件的读取需要注意文件头部的`<?xml version="1.0" encoding="gb2312"?>`声明,确保...