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 );
终于解决了这个乱码问题。