前几天JSP中文乱码的问题一直困扰着我,查了好多资料,好像讲的都不怎么好,没有能解决好。人还得靠自己,最终还是自己给解决了。讲讲思路:
一、概念认识
什么是编码:
关于编码的认识可能是不能解决中文乱码的根本原因。所谓编码,用我的理解就是将人能识别的符号、信息(文字、图像、声音等)转化为计算机可以存储、传输的格式就是编码,由于计算机的存储和传输是以字节为单位的,所以也可以说将符号信息转化为字节流的过程。但是因为符号信息有多种,希望存储的方式也不一样,所以就有了不同的编码方式,对于符号(文字信息)来说就是字符集,字符集就是编码的规范。
什么是解码:
知道了编码,解码就不难理解了。因为之前我们为了能存储和传输特定类型的信息,将这些信息通过某种编码方式变成了字节流,当然如果想让这些信息还原成人能够识别的格式当然要将其通过原来的编码规范变成特定的序列,这个过程就是解码。
关于编码和解码简单的说法:
编码就是将信息变成计算机能够识别的字节码的过程,解决就是将计算机存储按照正确的格式还原成人可以识别的格式的过程。
二、出现乱码的原因
1存储与读取:
在存储的时候将汉字使用某种编码方式转换成了字节流,而在重新读取这些字节流以解码成相应的汉字时去使用了另外的编码方式,错误的原因是可能是使用较短的ISO-8859-1编码存储,而使用了可能是GBK、GB2312、UTF-8解码,或是使用了较长的GBK、GB2312、或是UT-8作编码存储,而使用了较短的编码如ISO-8859-1编码解码。
2网页显示:
A、当从网页从客户端提交信息到服务器端时,彩的编码一般为ISO-8859-1方式,因此,为了获得正确的汉字显示,应采用相同的编码将取得的信息解码。
B、将汉字显示到客户端面页面时,应使用与网页指定的字符集相同或相兼容的编码方式编码后再发送到客户端网页。
三、问题的解决
这里通过几个例子来说明如果避免乱码的出现。
String类的getBytes()方法。getBytes()方法的无参数调用,是将汉字通过Java系统默认编码方式将字符编码为字节,在Windows平台下,Java编译系统的默认编码是GBK。而getBytes(String encoding)这个方法,可以让编程者自己指定汉字串应该采用的编码方式。
例1:
String demo
=
"
这是一个汉字
"
;
String gbk
=
demo.getBytes();
//
相当于写成demo.getBytes("GBK");
String gb2312
=
demo.getBytes(
"
GB2312
"
);
....
我们可以通过上面的方法将得汉字编码成某种字符集做存储、传输用。
例2:
这里假设我们从客户端得到了一个Post请求,现在我们要取得表单中的汉字。
String somePara =
request.getParameter(
"
para1
"
);
//
para1是一个带有汉字的表单项
//
现在我们要得到一个以UTF-8为编码方式的汉字
String newStr
=
new
String(somePara.getBytes(
"
ISO-8859-1
"
),
"
UTF-8
"
);
//
现在我们把这个汉字显示到客户端页面去
request.getWriter().print(newStr);
上面的程序中,使用了一个String类的构造方法String(bytes[] b, String encoding),这个方法可以将给定的字节数组解码成指定编码方式的字符串,在编码种使用的比较多。
例3:
这里我们假设有一个文件是用UTF-8方式存储的,现在我们想把它软件化为ISO-8859-1的方式存储。
// 建立文件输入流
File f;
FileInputStream fis;
FileOutputStream fosl;
try ...
{
f=new File("a.txt");
fis=new FileInputStream(fs);
//先获取到文字的长度
int len=fs.avilable();
if(-1!=len)...{
byte[] b=new byte[len];
fs.read(b);
fis.close();
//我们把得到的字节数组变成字符串,注意这是这个数组是UTF-8编码的字节序列
String str=new String(b,"UTF-8");//我们仍采用UTF-8将其解码
//现在我们将得到的字符串重新编码回ISO-8859-1再存储成另一个文件
fos=new FileOutputStream(f);
fos.write(str.getBytes("ISO-8859-1"));
fos.close();
}
}
catch (IOException e)
... {
e.printStackTrace();
}
上面的例子中我们注意到使用最多的其实就是String类的getBytes()方法,这个方法可以将一个字符串转换成任意一种编码方式的字节序列(用专业点的话说就是编码将字符串作编码成任何字符集),另外一个就是String类的一个构造方法 String(byte[] b,String encoding),通过这个方法我们可以将已经被编码成某种字符集的字符串的字节数组按照它原来的字符集重新解码成字符串。
只要理解了编码和解码的含义,并掌握了什么时候应该编码,什么时候应该解码,怎么编码及怎么解码,Java的汉字问题其实还是很容易解决的。