论坛首页 入门技术论坛

UTF-8在Web开发中乱码的解决方案

浏览 3724 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-10-11  
 

UTF-8Web开发中乱码的解决方案

软件环境:

OSwindowXP sp2

JVMjdk1.6

IDEelcipse3.2.2

ASTomcat6.0.14

DBMySQL Community Edition 5.0.45-community-nt (GPL)

<o:p> </o:p>

UTF-8编码格式将是众望所归,而用UTF-8格式开发软件的同胞们或多或少遇到过乱码的困惑,乱码的产生关联的系统的每个环节,从编写jsp页面到响应用户请求返回html流之间的每个环节都会导致乱码的产生。那么我们就每个环节逐一进行处理使乱码无处藏身。

这里我们并不是专业研究编码的格式的,所以对于各种编码的内部格式和编码之间的转换细节将不做讨论。

下面我们就沿着这一条路来具体看一看软件编写的每个环节:

Jsp----〉用户请求和服务器响应------〉数据库存储读取-----〉返回html页面

<o:p> </o:p>

第一步:jsp页面的编写。编写jsp页面工具众多这里不一一举例,只需要把编写工具的编码格式设置为UTF-8格式,就可以保证你的源文件格式为UTF-8。初步杜绝乱码的产生。遇到过很多次同时在不同开发工具下文件互拷时出现乱码,这就是编码格式不同造成的。下图是eclipse中设置项目的编码格式:<o:p></o:p>

<v:shapetype id="_x0000_t75" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" filled="f" stroked="f" coordsize="21600,21600" o:spt="75"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" o:extrusionok="f" gradientshapeok="t"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id="Picture_x0020_0" style="VISIBILITY: visible; WIDTH: 380.25pt; HEIGHT: 278.25pt; mso-wrap-style: square" alt="eclipse.JPG" type="#_x0000_t75" o:spid="_x0000_i1028"><v:imagedata o:title="eclipse" src="file:///C:\DOCUME~1\giga\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.jpg"></v:imagedata></v:shape>

图一

选中一个项目,右键properties将出现上图。Eclipse默认会和系统编码方式一样,如果是中文系统那么默认的编码方式是GBK。所以,我们必须修改为UTF-8

<o:p> </o:p>

IDE设置好并不能保证jsp页面的安全,我们知道jsp文件也有自己的编码格式,那么我们要记得在jsp文件的头部添加下面一句话:

<!---->

这样就能保证jsp文件一post的方式提交请求时编码格式为UTF-8

第二步:Jsp页面运行后,服务器会响应从客户端传来的请求,分一下两种情况:

1Method=get

2Method=post

由于在jsp页面头部设置了contentType值这样能保证从客户端提交的请求编码格式为UTF-8

pageEncoding的值保证页面输出时的编码,即返回客户端的数据编码为UTF-8

Tomcat在响应请求时,对于post方式请求会以mime设置的UTF-8编码格式进行编码,而get方式提交的请求,则以tomcat默认的ISO-8859-1。除非你能保证你所有的提交请求都是post类型的(恐怕无人能做这个保证),那么你必须要进行设置处理。一般通常程序员会想到通过Filter或在servlet中对请求重编码。其实我们可以在tomcat中设置响应请求的编码格式。

我们找到tomcat中的配置文件server.xml找到端口8080Connector在后面添加

URIEncoding="UTF-8"即可。

即修改后的Connector代码段为:

<o:p> </o:p>

  1. <Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
  2.  enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" 
  3. connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8"/>  

<connector uriencoding="UTF-8" maxthreads="150" debug="0" redirectport="8443" port="8080" enablelookups="false" maxsparethreads="75" minsparethreads="25" connectiontimeout="20000" disableuploadtimeout="true" acceptcount="100"></connector>

<o:p> </o:p>

有些朋友不知从哪里看得信息,以致对Connector 中的useBodyEncodingForURI产生疑惑,其实朋友们可以试验一下,如果我们设置了URIEncoding="UTF-8",那么无论useBodyEncodingForURI设置falsetrue都不会影响正常响应。

<o:p> </o:p>

另外网上还有如下说法:

tomcat5中,因为众所周知的原因,为了保证get/post数据都采用相同的UTF8编码,我们在server.xml中进行了如下设置:

<connector maxthreads="150" port="8080" minsparethreads="25" span=""></connector>

xml 代码
  1. <Connector port="8080" maxThreads="150" minSpareThreads="25"    
  2. maxSpareThreads="75" enableLookups="false" redirectPort="8443"    
  3. acceptCount="100" debug="99" connectionTimeout="20000"    
  4. disableUploadTimeout="true" URIEncoding="UTF-8"/>  

这里指定了定了get时候的数据编码。但是,当使用IIS转发请求时。如果直接通过tomcat响应请求时,则无需关心。get时候的数据编码。但是,当使用IIS作为webserver转发servlet/jsp请求给Tomcat时候,这个设置却失效了。其实原因很简单:IIS是通过AJP协议,把请求转发到Tomcat监听的8009端口上的,所以这里针对8080的设置自然就无效了。正确的方法是进行下面的设置:

<connector redirectport="8443" port="8009" enablelookups="false" span=""></connector>

xml 代码
  1. <Connector port="8009" enableLookups="false" redirectPort="8443"    
  2. debug="0" protocol="AJP/1.3" URIEncoding="UTF-8"/>  

这里指出了一个特例,就是当设置了

第三步:下面我们看一下最重要的部分,数据的存储。如果我们的数据不能以正确地格式存储,那么我们得到的将是一堆垃圾,我们的软件也变得毫无意义。在UTF-8大行其道的今天众多DB软件都支持这一个格式。商用数据库软件都能完美支持众多格式,我们今天来看一下另众多开源者热捧的DB软件mysql。我们可以使用Mysql Server Instence Config Wizardmysql的编码进行设置:

<v:shape id="Picture_x0020_1" style="VISIBILITY: visible; WIDTH: 345pt; HEIGHT: 264.75pt; mso-wrap-style: square" alt="mysql.JPG" type="#_x0000_t75" o:spid="_x0000_i1027"><v:imagedata o:title="mysql" src="file:///C:\DOCUME~1\giga\LOCALS~1\Temp\msohtmlclip1\01\clip_image003.jpg"></v:imagedata></v:shape>

图二

在此我们选择utf8即可。我们也可以手动修改mysql安装路径下的my.ini进行修改:

default-character-set=utf8

大部分开发者已经非常衷爱mysql的命令符操作了,但是如果存入数据为UTF-8格式的中文字体或者16位编码语言。那么我们将看到下图:

<v:shape id="Picture_x0020_3" style="VISIBILITY: visible; WIDTH: 415.5pt; HEIGHT: 272.25pt; mso-wrap-style: square" alt="data.JPG" type="#_x0000_t75" o:spid="_x0000_i1026"><v:imagedata o:title="data" src="file:///C:\DOCUME~1\giga\LOCALS~1\Temp\msohtmlclip1\01\clip_image005.jpg"></v:imagedata></v:shape>

图三

我们执行查询语句后得到的将是一些乱码信息。这个原因主要是因为命令行的编码限制,如下图:

<v:shape id="Picture_x0020_4" style="VISIBILITY: visible; WIDTH: 285pt; HEIGHT: 327.75pt; mso-wrap-style: square" alt="cmd.JPG" type="#_x0000_t75" o:spid="_x0000_i1025"><v:imagedata o:title="cmd" src="file:///C:\DOCUME~1\giga\LOCALS~1\Temp\msohtmlclip1\01\clip_image007.jpg"></v:imagedata></v:shape>

图四

我们这里就看到中文系统的命令台窗口只支持两种编码格式,那么对于UTF-8格式的文本当然无能为力了。

Mysql设置好编码格式并不能说明我们就一定能以我们想要的UTF-8格式存储我们的数据,从我们的持久层类把数据存入数据库中间还有一个编码转换问题,我们同样需要明确的指出以UTF-8的格式进行数据的转换(实际上就是数据的传输)。就像我们的电视信号发射台处理数据,电视机内部的线路为数据线路处理数据信号,但是如果以模拟的方式传递信号,那么我们的电视上将显示乱码(早期黑白电视时将看到满屏雪花,现在我们看到最多的可能是蓝屏或者电视品牌的画面了)。

我们只要在我们的数据库联接配置文件中指定URI时这样指定:

<property name="url" value="jdbc:mysql://localhost:3306/book&amp;lt;strong style=">
xml 代码
</property>
  1. <property name="url" 
  2. value="jdbc:mysql://localhost:3306/book?characterEncoding=utf-8" />  

黑体部分将告诉系统,数据以UTF-8格式进行传输。这样的话我们就能保证数据从数据持久层传出传入数据库是的格式为UTF-8格式的。最后就是数据的显示,数据的现实是数据存储的逆过程,我们从数据储存可以看到每一个环节编码格式都是我们所期待的UTF-8。我们在前面jsp页面里边设置了pageEncoding=UTF-8这样就能保证我们服务器返回客户端的数据也是以UTF-8格式进行编码。毫无疑问我们将得到正确的编码。

到次我们已经循这数据流经的途径走了一遍,对每个细节每个流转途径对数据的格式进行设定,我们的UTF-8探讨也将告一段落。由于时间关系,难免会有贻误,欢迎广大网友探讨指正。

论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics