2023年11月28日发(作者:)

JSP中文乱码问题综述

2010-08-10 14:25:31

一、Java中文问题的由来

Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中

文乱码问题的麻烦。原因主要有两方面,JavaJSP文件本身编译时产生的乱码问题和Java程序于其

他媒介交互产生的乱码问题。

首先Java(包括JSP)源文件中很可能包含有中文,而JavaJSP源文件的保存方式是基于字节流的,

如果JavaJSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。

于这种乱码,建议在Java文件中尽量不要写中文(注释部分不参与编译,写中文没关系),如果必须写

的话,尽量手动带参数-ecoding GBK或-ecoding gb2312编译;对于JSP,在文件头加上<%@ page

contentType=text/html;charset=GBK%><%@ page contentType=text/html;charset=gb2312%>基本上

就能解决这类乱码问题。

二、常见的解决方式

1,最基本的乱码问题。

这个乱码问题是最简单的乱码问题。一般新会出现。就是页面编码不一致导致的乱码。

<%@ page language=java pageEncoding=UTF-8%>

<%@ page contentType=text/html;charset=iso8859-1%>

</span><span style='font-size:14.94px;color:#000000;font-family:SimSun;'>中文问题</span><span style='font-size:14.94px;color:#000000;letter-spacing:0.028px;font-family:SimSun;'>

我是个好人

三个地方的编码。

第一个地方的编码格式为jsp文件的存储格式。Ecljpse会根据这个编码格式保存文件。并编译jsp

件,包括里面的汉字。

第二处编码为解码格式。因为存为UTF-8的文件被解码为iso8859-1,这样如有中文肯定出乱码。也就

是必须一致。而第二处所在的这一行,可以没有。缺省也是使用iso8859-1的编码格式。所以如果没有

这一行的话,“我是个好人”也会出现乱码。必须一致才可以。

第三处编码为控制浏览器的解码方式。如果前面的解码都一致并且无误的话,这个编码格式没有关系。

有的网页出现乱码,就是因为浏览器不能确定使用哪种编码格式。因为页面有时候会嵌入页面,导致浏

览器混淆了编码格式。出现了乱码。

2,表单使用Post方式提交后接收到的乱码问题

这个问题也是一个常见的问题。这个乱码也是tomcat的内部编码格式iso8859-1在捣乱,也就是说post

提交时,如果没有设置提交的编码格式,则会以iso8859-1方式进行提交,接受的jsp却以utf-8的方

式接受。导致乱码。既然这样的原因,下面有几种解决方式,并比较。

A,接受参数时进行编码转换

String str = new String(ameter(something).getBytes(ISO-8859-1),utf-8) 这样

的话,每一个参数都必须这样进行转码。很麻烦。但确实可以拿到汉字。

B,在请求页面上开始处,执行请求的编码代码, racterEncoding(UTF-8),把提交内容

的字符集设为UTF8。这样的话,接受此参数的页面就不必在转码了。直接使用String str =

ameter(something);即可得到汉字参数。但每页都需要执行这句话。这个方法也就对

post提交的有效果,对于get提交和上传文件时的enctype=multipart/form-data是无效的。稍后下面

单独对这个两个的乱码情况再进行说明。

C,为了避免每页都要写racterEncoding(UTF-8),建议使用过滤器对所有jsp

进行编码处理。

如果不想在每个文件里都写这样两句话,更简洁的办法是使用Servlet规范中的过虑器指定编码,过滤

器的在中的典型配置和主要代码

如下:

:

CharacterEncodingFilter

terEncodingFilter

encoding

GBK

CharacterEncodingFilter

/*

:

public class CharacterEncodingFilter implements Filter

{

protected String encoding = null;

3,表单get提交方式的乱码处理方式。

如果使用get方式提交中文,接受参数的页面也会出现乱码,这个乱码的原因也是tomcat的内部

编码格式iso8859-1导致。Tomcat会以get的缺省编码方式iso8859-1对汉字进行编码,编码后追加到

url,导致接受页面得到的参数为乱码/、。

解决办法:

A,使用上例中的第一种方式,对接受到的字符进行解码,再转码。

BGet走的是url提交,而在进入url之前已经进行了iso8859-1的编码处理。要想影响这个编码则需

要在Connector节点增加useBodyEncodingForURI=true

属性配置,即可控制tomcatget方式的汉字编码方式,上面这个属性控制get提交也是用

racterEncoding(UTF-8)所设置的编码格式进行编码。所以自动编码为utf-8,接受页面

正常接受就可以了。但我认为真正的编码过程是,tomcat又要根据

maxThreads=150 minSpareThreads=25 maxSpareThreads=75

enableLookups=false redirectPort=8443 acceptCount=100

debug=0 connectionTimeout=20000 useBodyEncodingForURI=true

disableUploadTimeout=true URIEncoding=”UTF-8”/>

里面所设置的URIEncoding=”UTF-8”再进行一次编码,但是由于已经编码为utf-8再编码也不会有变

化了。如果是从url获取编码,接受页面则是根据URIEncoding=”UTF-8”来进行解码的。

4,上传文件时的乱码解决

上传文件时,form表单设置的都是enctype=multipart/form-data这种方式以流方式提交文件。

果使用apach的上传组件,会发现有很多乱码现象。这是因为apach的先期

bug取出汉字后进行解码,因为这种方式提交,编码又自动使用的是tomcat缺省编码格式iso-8859-1

但出现的乱码问题是:句号,逗号,等特殊符号变成了乱码,汉字如果数量为奇数,则会出现乱码,偶

数则解析正常。

解决方式: 下载 这个版本的jar已经解决了这些bug

但是取出内容时仍然需要对取出的字符进行从iso8859-1utf-8转码。已经能得到正常所有汉字以及

字符。

5Java代码关于url请求,接受参数的乱码

url的编码格式,取决于上面所说的URIEncoding=”UTF-8”。 如果设定了这个编码格式,则意味着所

有到url的汉字参数,都必须进行编码才可以。否则得到的汉字参数值都是乱码,例如

一个链接 rect(“/?name=张大维”);而在里面直接使用

String name = ametername);得到的就是乱码。因为规定了必须是utf-8才可以,

所以,这个转向应该这样写:

rect(“/?name=(“张大维”,”utf-8”);才可以。

如果不设置这个参数URIEncoding=”UTF-8”, 会怎么样呢? 不设置则就使用了缺省的编码格式

iso8859-1。问题又出来了,第一就是参数值的个数如果是奇数个数,则就可以正常解析,如果使偶数个

数,得到最后字符就是乱码。还有就是如果最后一个字符如果是英文,则就能正常解析,但中文的标点

符号仍出现乱码。权宜之计,如果您的参数中没有中文标点符号,则可以在参数值最后加一个英文符号

来解决乱码问题,得到参数后再去掉这个最后面的符号。也可以凑或使用。

6,脚本代码关于url请求,接受到的参数乱码

脚本中也会进行页面转向的控制,也会涉及到附带参数,并在接受页面解析这个参数的情况。如果

这个汉字参数不进行URIEncoding=”UTF-8”所指定的编码处理,则接受页面接受到的汉字也是乱码。

脚本处理编码比较麻烦,必须有相应的编码脚本对应文件,然后调用脚本中的方法对汉字进行编码即可。

7,关于jspMyEclipse中打开的乱码问题

对于一个已经存在的项目,Jsp文件的存储格式可能是utf-8。如果新安装的eclipse,则缺省打

开使用的编码格式都是iso8859-1。所以导致 jsp里面的汉字出现乱码。这个乱码比较容易解决,直接

eclipse3.1的偏好设置里面找到general-edidor设置为您的文件打开编码为utf-8即可。Eclipse

会自动重新以新的编码格式打开。汉字即可正常显示。

8,关于html页面在eclipse中打开出现乱码情况

由于大部分页面都是由dreamweaver制作,其存储格式跟eclipse的识别有差别导致。

一般这种情况,在eclipse中新建一个jsp,直接从dreamweaver复制页面内容粘贴到jsp即可。

jsp开发过程中会遇到各种中文乱码问题,对乱码的

处理方法也有所不同!究其原因.大部分是因为编码默认采用

ISO-8859-1或者是编码不一致导致的,悲剧的是默认的ISO-8

859-1编码不支持中文!(,中国...感慨一下,不解释)所幸,UTF

-8,GBK,GB2312都是支持中文的!

1. jsp页面中文乱码 这种乱码最常见也最好解决

page指令中添加页面内容和显示方式的设置,如下两种都可

:

<%@ page language="java" import=".*" pageE

ncoding="gb2312"%>

<%@ page language="java" import=".*" Conte

ntType="text/html;charset=gb2312"%>

有人会问pageEncodingContentType有什么区别,

单说

contentType指定的是JSP页最终 Browser(客户端)所见

到的网页内容的编码

pageEncoding指定JSP编写时所用的编码

2.

表单提交中文乱码 当用Request对象获取客户提交

的汉字代码的时候,会出现乱码

Method=”POST”

接收数据的文件中要加入<% racterEncodi

ng("gb2312");%>

3.

中文作为参数传递乱码

new String(es("ISO-8859-1"), "gb2312

")这句代码是转换编码格式的关键,这种转码方式还可以用

在读取数据库中文乱码的转码!但要是原来的字符编码不是I

SO-8859-1时这个方法就会失效,出错!

try{

byte[] tempByte = es("GB2312");

uniStr = new String(tempByte,"ISO8859_1");

}catch(Exception ex){

}

你也可以在直接的转换,首先你将获取的字符串用

ISO-8859-1进行编码,然后将这个编码存放到一个字节数组

中,然后将这个数组转化成字符串对象就可以了,例如:

String str=ameter(“字符串”);

Byte B[]=es(“ISO-8859-1”);

Str=new String(B);

4.

读取cookie时出现乱码

写入cookie时先编码

Cookie nameCookie = new Cookie("name", .U

(strname,"GB2312"));

读取cookie时再解码

String name=(name,"GB23

12")

或者采用树上第136页的方法

写入cookie时先编码,将汉字编码转换为Unicode

码,解决汉字乱码问题

读取cookie时再解码,将Unicode编码转换为汉字编

码,解决汉字乱码问题

2. 编码基本知识

最早的编码是iso8859-1,和ascii编码相似。但为了方便表

示各种各样的语言,逐渐出现了很多标准编码,重要的有如

下几个。

2.1. iso8859-1

属于单字节编码,最多能表示的字符范围是0-255,应用于

英文系列。比如,字母'a'的编码为0x61=97

很明显,iso8859-1编码表示的字符范围很窄,无法表示中文

字符。但是,由于是单字节编码,和计算机最基础的表示单

位一致,所以很多时候,仍旧使用iso8859-1编码来表示。

而且在很多协议上,默认使用该编码。比如,虽然"中文"

个字不存在iso8859-1编码,以gb2312编码为例,应该是"d

6d0 cec4"两个字符,使用iso8859-1编码的时候则将它拆开

4个字节来表示:"d6 d0 ce c4"(事实上,在进行存储的时

候,也是以字节为单位处理的)。而如果是UTF编码,则是

6个字节"e4 b8 ad e6 96 87"。很明显,这种表示方法还需要

以另一种编码为基础。

2.2. GB2312/GBK

这就是汉子的国标码,专门用来表示汉字,是双字节编码,

而英文字母和iso8859-1一致(兼容iso8859-1编码)其中g

bk编码能够用来同时表示繁体字和简体字,而gb2312只能

表示简体字,gbk是兼容gb2312编码的。

2.3. unicode

这是最统一的编码,可以用来表示所有语言的字符,而且是

定长双字节(也有四字节的)编码,包括英文字母在内。所

以可以说它是不兼容iso8859-1编码的,也不兼容任何编码。

不过,相对于iso8859-1编码来说,uniocode编码只是在前面

增加了一个0字节,比如字母'a'"00 61"

需要说明的是,定长编码便于计算机处理(注意GB2312/GB

K不是定长编码),而unicode又可以用来表示所有字符,所

以在很多软件内部是使用unicode编码来处理的,比如java

2.4. UTF

考虑到unicode编码不兼容iso8859-1编码,而且容易占用更

多的空间:因为对于英文字母,unicode也需要两个字节来表

示。所以unicode不便于传输和存储。因此而产生了utf编码,

utf编码兼容iso8859-1编码,同时也可以用来表示所有语言

的字符,不过,utf编码是不定长编码,每一个字符的长度从

1-6个字节不等。另外,utf编码自带简单的校验功能。一般

来讲,英文字母都是用一个字节表示,而汉字使用三个字节。

注意,虽然说utf是为了使用更少的空间而使用的,但那只

是相对于unicode编码来说,如果已经知道是汉字,则使用

GB2312/GBK无疑是最节省的。不过另一方面,值得说明的

是,虽然utf编码对汉字使用3个字节,但即使对于汉字网

页,utf编码也会比unicode编码节省,因为网页中包含了很

多的英文字符。