轉(zhuǎn)自: 落葉空嘆飄花翎 http://www.itpub.net/336395,1.html
Java 開(kāi)發(fā)中遇到的亂碼問(wèn)題
若想明白jsp開(kāi)發(fā)過(guò)程中為什么會(huì)產(chǎn)生中文亂碼,我們先來(lái)看看unicode編碼。
Unicode (統(tǒng)一碼)顧名思義是一個(gè)將世界上各種文字統(tǒng)一在一起的東東。由美國(guó)各大電腦廠商組成的Unicode策進(jìn)會(huì)來(lái)推動(dòng)。目的,推廣一個(gè)世界通用的編碼體制,驚世界上所有常用的文字都涵蓋進(jìn)去,從而減少個(gè)電腦商開(kāi)發(fā)國(guó)外市場(chǎng)遇到的問(wèn)題。
為了將成千上萬(wàn)的文字統(tǒng)統(tǒng)收集到一個(gè)共同的編碼機(jī)制下,在兼顧經(jīng)濟(jì)的原則下,不管是東方還是西方文字,每個(gè)字在Unicode中一律以?xún)蓚€(gè)Bytes來(lái)表示,這樣至少有2的16次方65536種不同的組合,足以應(yīng)付目前絕大多數(shù)場(chǎng)合的需要。
基本上,計(jì)算機(jī)只是處理數(shù)字。它們指定一個(gè)數(shù)字,來(lái)儲(chǔ)存字母或其他字符。在創(chuàng)造Unicode之前,有數(shù)百種指定這些數(shù)字的編碼系統(tǒng)。沒(méi)有一個(gè)編碼可以包含足夠的字符:例如,單單歐州共同體就需要好幾種不同的編碼來(lái)包括所有的語(yǔ)言。即使是單一種語(yǔ)言,例如英語(yǔ),也沒(méi)有哪一個(gè)編碼可以適用于所有的字母,標(biāo)點(diǎn)符號(hào),和常用的技術(shù)符號(hào)。
這些編碼系統(tǒng)也會(huì)互相沖突。也就是說(shuō),兩種編碼可能使用相同的數(shù)字代表兩個(gè)不同的字符,或使用不同的數(shù)字代表相同的字符。任何一臺(tái)特定的計(jì)算機(jī)(特別是服務(wù)器)都需要支持許多不同的編碼,但是,不論什么時(shí)候數(shù)據(jù)通過(guò)不同的編碼或平臺(tái)之間,那些數(shù)據(jù)總會(huì)有損壞的危險(xiǎn)。
Unicode給每個(gè)字符提供了一個(gè)唯一的數(shù)字,不論是什么平臺(tái),不論是什么程序,不論什么語(yǔ)言。Unicode標(biāo)準(zhǔn)已經(jīng)被這些工業(yè)界的領(lǐng)導(dǎo)們所采用,例如:Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys和其它許多公司。最新的標(biāo)準(zhǔn)都需要Unicode,例如XML, Java, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML等等,并且,Unicode是實(shí)現(xiàn)ISO/IEC 10646的正規(guī)方式。許多操作系統(tǒng),所有最新的瀏覽器和許多其他產(chǎn)品都支持它。Unicode標(biāo)準(zhǔn)的出現(xiàn)和支持它工具的存在,是近來(lái)全球軟件技術(shù)最重要的發(fā)展趨勢(shì)。
將Unicode與客戶(hù)服務(wù)器或多層應(yīng)用程序和網(wǎng)站結(jié)合,比使用傳統(tǒng)字符集節(jié)省費(fèi)用。Unicode使單一軟件產(chǎn)品或單一網(wǎng)站能夠貫穿多個(gè)平臺(tái),語(yǔ)言和國(guó)家,而不需要重建。它可將數(shù)據(jù)傳輸?shù)皆S多不同的系統(tǒng),而無(wú)損壞。
在與Unicode相關(guān)的各技術(shù)文件中,經(jīng)常會(huì)看到ISO 10646和UCS這兩個(gè)名詞。
ISO是位于瑞士的國(guó)際標(biāo)準(zhǔn)局的縮寫(xiě)。
UCS為ISO頒布的第10646號(hào)標(biāo)準(zhǔn) Universal Character Set,就是世界通用字符集。
UCS通用字符集采用4個(gè)Bytes來(lái)編碼,將世界上所有的官用和商用編碼大小通吃,一網(wǎng)打盡。Unicode自1991年便和ISO的UCS小組密切配合,讓Unicode和ISO 10646保持一致。因此Unicode 自2.0版開(kāi)始,便和 ISO 10646-1使用相同的編碼。
康熙字典中的漢字有4萬(wàn)7千,如果再加上里面沒(méi)有的簡(jiǎn)體字,和不同寫(xiě)法的日文字,那么 Unicode6萬(wàn)多的分配空間,光用來(lái)分配漢字就顯得捉禁見(jiàn)晝,更別說(shuō)什么泰文,阿拉伯等其他文字了。針對(duì)這個(gè)問(wèn)題Unicode和UCS采用了[中日韓文整合](CJK Unification)的解決方案,把中日韓筆畫(huà)詳盡的漢字用同一個(gè)單碼表示。
經(jīng)過(guò)[中日韓文整合]的Unicode稱(chēng)為統(tǒng)漢字Unihan。
完整的Unicode4.0版可由http://www.unicode.org/Public/UNIDATA/Unihan.txt 下載。
UTF (Unicode/UCS Transformation Format),Unicode推薦使用UTF-8和UTF-16兩種格式其中8和16指的是Bits數(shù)而不是Bytes數(shù)。
UTF-16基本就是Unicode雙字節(jié)的實(shí)現(xiàn),加上一個(gè)應(yīng)付未來(lái)需要的擴(kuò)充編碼機(jī)制(很少用)
UTF-8 是一種不等幅的編碼方式,英數(shù)字(Ascii字碼)保持原狀,完全不受影響(因此不需要做轉(zhuǎn)換),而其他漢字資料須透過(guò)程序來(lái)轉(zhuǎn)換,會(huì)[變胖],因?yàn)槊總€(gè)字需要額外一個(gè)或兩個(gè)Bytes來(lái)編碼。
UCS字符集中,有UCS-2和UCS-4等編碼方式其中的2和4指的是bytes數(shù),對(duì)應(yīng)UTF-8和UTF-16.
UCS-2基本和Unicode雙byte 編碼差不多
UCS-4四 byte編碼表示一個(gè)字,在每個(gè) UCS-2前面加上兩個(gè)空白的Byte,便可得到對(duì)應(yīng)的 UCS-4。
Unicode的空間分配:
以下Unicode區(qū)位碼均以16進(jìn)制表示
Unicode的前256個(gè)字符和ISO-8859-1(西歐字母)完全相同,其中前半段就是Ascii(u+0000到u+00FF)。每個(gè)ISO-8859-1碼前面補(bǔ)上一個(gè)空byte(0x00)后才是相應(yīng)的Unicode碼。
和我們切身相關(guān)的Unihan主要分布在u+3400到u+F9FFF之間,GB2312和BIG5主要分布在u+4E00到U+9FFF之間。
UTF-8的編碼原理和特性:
知道了西歐字符和漢字在Unicode中的位置后,來(lái)看看UTF-8
U+0000~U+007E 1 _ _ _ _ _ _ _ (7bits)
U+0080~U+07FF 1 1 0_ _ _ _ _ 1 0_ _ _ _ _ _ (11bits)
U+0800~U+FFFF 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ (16bits)
看一看Unicode三種格式提出自由的bits(下劃線空位)是否足以用來(lái)代表區(qū)位中各Unicode碼,剛好夠用。
那么當(dāng)程序處理UTF-8編碼文件時(shí),如何得知一個(gè)字符的疆界落在哪里?還有到底他是以三種形式那一中出現(xiàn)呢?
每個(gè)以UTF-8編碼的字符,不管是以一、二、三個(gè)bytes出現(xiàn),第一個(gè)byte前端都清楚地標(biāo)示了該字符的byte總數(shù)。如110種有兩個(gè)1,代表這種字符是以第二種方式出現(xiàn),由兩個(gè)bytes組成。而1110有三個(gè)1,表示這種字符一點(diǎn)種方式出現(xiàn),由三個(gè)字節(jié)組成。
每個(gè)多重byte的UTF-8編碼有一個(gè)共同的通性,即其中的第二個(gè)第三個(gè)byte, 一律以10兩個(gè)bits開(kāi)頭。由于其中的最高位總設(shè)成1,可以很容易和那些在UTF-8中只用一個(gè)Byte的ASCII字元區(qū)分開(kāi)來(lái),方便偵錯(cuò)。
因?yàn)樯鲜鲈O(shè)計(jì)特點(diǎn),UTF-8和Unicode之間,可以很容易做雙向自由轉(zhuǎn)換,而不會(huì)丟失任何資料。
解決辦法:亂碼問(wèn)題在 NT操作系統(tǒng)我沒(méi)怎么碰到過(guò),但是在UNIX 或LINUX系統(tǒng)上出現(xiàn)的比較多
由于操作系統(tǒng)和使用環(huán)境不一樣,產(chǎn)生亂碼的方式也不一樣,但是如果掌握了上面的Unicode 編碼原理,自己仔細(xì)分析一下,很多問(wèn)題便可迎刃而解。
下面看看幾個(gè)常見(jiàn)的例子。
1. 如果一些網(wǎng)站服務(wù)器例如Tomcat 如果遇到中文亂碼問(wèn)題,可以修改conf目錄下的server.xml
<Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100" debug="0"connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"/>
URIENcoding 設(shè)成GBK或GB2312
2. 表單中或傳遞字符串:本來(lái)輸入的漢字是正常的,但是提交后再顯示出來(lái)是亂碼,因?yàn)樘峤坏囊话闶?ISO8859編碼,所以顯示的時(shí)候要轉(zhuǎn)成GB2312編碼:
String S=new String(rs.getString("news").getBytes("gb2312"),"ISO8859_1");
//rs為待轉(zhuǎn)換的字符串
然后使用S字符串的值就可以了
3. 有的服務(wù)器端的語(yǔ)言環(huán)境如果設(shè)成簡(jiǎn)體中文的也可以解決此類(lèi)問(wèn)題
4. 插入數(shù)據(jù)庫(kù)中的字符是亂碼
看看數(shù)據(jù)庫(kù)中支持的是何種編碼方式,用類(lèi)似2中的方式作一下轉(zhuǎn)換即可。
5. 總之,用jsp開(kāi)發(fā),碰到亂碼,你得分析是讀的時(shí)候發(fā)生亂碼,還是寫(xiě)的時(shí)候發(fā)生亂碼,用2中的轉(zhuǎn)換,基本就能解決問(wèn)題,有些時(shí)候?qū)懙臅r(shí)候做一次轉(zhuǎn)換,例如:
String S=new String(rs.getString("news").getBytes("gb2312"),"ISO8859_1");
//讀的時(shí)候在轉(zhuǎn)換回來(lái)
String S=new String(rs.getString("news").getBytes("ISO8859_1"),"GB2312");
或者把ISO8859-1和GB2312 的位置換一下,自己多試試,就能找到解決問(wèn)題的辦法。
Java_struts 入門(mén)快速手冊(cè)
----by omencathay
Struts
簡(jiǎn)介
1、 Struts基于MVC模式 Model(Bean) ,View(jsp文件), Control (Action類(lèi),ActionForm類(lèi))
2、 開(kāi)發(fā)準(zhǔn)備
struts http://jakarta.apache.org/struts
jdk1.2版本以上 http://java.sun.com/j2se
Xerces XML parser http://xml.apache.org/xerces-j
下載struts后,解壓zip文件到一個(gè)臨時(shí)目錄;然后拷貝struts.jar, jakarta-oro.jar, jdbc2_0-stdext.jar和common*.jar文件到你所應(yīng)用struts的WEB-INF/lib目錄下;拷貝struts*.tld文件和*.dtd文件到WEB-INF目錄下,確定該才提到的所有的jar包都在web應(yīng)用服務(wù)器的 classpath環(huán)境變量上設(shè)置。
3、 配置 (兩個(gè)xml文件:web.xml, struts-config.xml)
配置web.xml,第一件事情就是注冊(cè)組件action servlet,<servlet> .. </servlet>標(biāo)簽封裝了整個(gè)struts 框架的應(yīng)用程序
<!-- Action Servlet Configuration -->
1 <servlet>
2 <servlet-name>action</servlet-name>
3 <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
4 <init-param>
5 <param-name>application</param-name>
6 <param-value>myApp.properties.ApplicationResources</param-value>
7 </init-param>
8 <init-param>
9 <param-name>config</param-name>
10 <param-value>/WEB-INF/struts-config.xml</param-value>
11 </init-param>
12 </servlet>
13 <!-- Action Servlet Mapping -->
14 <servlet-mapping>
15 <servlet-name>action</servlet-name>
16 <url-pattern>*.do</url-pattern>
17 </servlet-mapping>
18 <!-- Application Tag Library Descriptor -->
19 <taglib>
20 <taglib-uri>/WEB-INF/lib/app.tld</taglib-uri>
21 <taglib-location>/WEB-INF/lib/app.tld</taglib-location>
22 </taglib>
23 <!-- Struts Tag Library Descriptor -->
24 <taglib>
25 <taglib-uri>/WEB-INF/lib/struts.tld</taglib-uri>
26 <taglib-location>/WEB-INF/lib/struts.tld</taglib-location>
27 </taglib>
28 <!-- Struts Tag Library Descriptors -->
29 <taglib>
30 <taglib-uri>/WEB-INF/lib/struts-bean.tld</taglib-uri>
31 <taglib-location>/WEB-INF/lib/struts-bean.tld</taglib-location>
32 </taglib>
33 <taglib>
34 <taglib-uri>/WEB-INF/lib/struts-form.tld</taglib-uri>
35 <taglib-location>/WEB-INF/lib/struts-form.tld</taglib-location>
36 </taglib>
37 <taglib>
38 <taglib-uri>/WEB-INF/lib/struts-logic.tld</taglib-uri>
39 <taglib-location>/WEB-INF/lib/struts-logic.tld</taglib-location>
40 </taglib>
41 <taglib>
42 <taglib-uri>/WEB-INF/lib/struts-template.tld</taglib-uri>
43 <taglib-location>/WEB-INF/lib/struts-template.tld</taglib-location>
44 </taglib>
注:最重要的部分是action-mappings 部分
<action-mappings>
每個(gè)<action>元素定義了特定的功能與相關(guān)聯(lián)的動(dòng)作類(lèi), 大多數(shù)action元素至少包括以下三個(gè)部分。
Path-----應(yīng)用程序映射的路徑
Type-----需要的完整的包和類(lèi)
Name-----action應(yīng)用的<form-bean>元素的名稱(chēng)
;
<forward>標(biāo)簽告訴struts框架將要跳轉(zhuǎn)到哪個(gè)jsp頁(yè)面;
<data-sources>標(biāo)簽給出數(shù)據(jù)源屬性;
4、 struts核心標(biāo)簽庫(kù)示例
1. Html:form
屬性:onsubmit
onsubmit屬性得到的是:表單提交時(shí)的javaScript事件句柄
用法:
(1).
Onsubmit 和 html:submit配合使用,javaScript函數(shù)返回true或false
<html:form action=”” onsubmit=”return javaScriptFunction();”>
和
<html:submit onclick=” javaScriptFunction();”/>
配合使用
在javaScriptFunction(){
}中加入return true和return false
html:from 根據(jù)返回的true或者false決定是否提交
等同于
(2)。
使用Html:button 要在javaScript函數(shù)中加入form.submit();
<html:form action=””>
<html:button onclick=” javaScriptFunction();”/>
form.submit();決定表單的提交
2. Html:text
Html:text是輸入框,可以修改數(shù)據(jù)做為property的值
如果要修改的屬性在bean中有g(shù)et\set方法,可以寫(xiě)為
<html:text name="listInfoFormBean" property="invoiceCode"/>
如果要修改的屬性在某一個(gè)VO里,在VO里對(duì)這一屬性有g(shù)et\set方法,在bean里對(duì)這一VO有g(shù)et\set方法,可以寫(xiě)為:
<html:text name="listInfoFormBean" property="tbInvStoresVO.invoiceCode"/>
3. Bean:write
Bean:write與html:text用法相似。只是bean:write輸出的數(shù)據(jù)是readonly的
這一點(diǎn)可以在html:text中加入屬性 readonly=”true”來(lái)實(shí)現(xiàn)
4. Html:select
<html:select property="invoicePurchaseCode" name=”beanname”>
<option value="0">----</option>
<option value="1">驗(yàn)舊供新</option>
<option value="2">交舊供新</option>
<option value="3">批量供應(yīng)</option>
</html:select>
name::bean的名稱(chēng)。如果沒(méi)有設(shè)置,將適用于這個(gè)內(nèi)嵌表單相關(guān)的formbean的名字
property:表單提交是送回的請(qǐng)求參數(shù)的名字,也是用來(lái)確定哪個(gè)屬性被選中的bean的屬性的名字
value:用來(lái)表明需要被選中的選項(xiàng)
怎么生成一個(gè)select:
option.options = new(value, lablename)
5. logic:iterate
logic:iterate的兩個(gè)用法
1. 在javaScript中初始化數(shù)組數(shù)據(jù)
//聲明數(shù)組
var invoiceWordCodeArray = new Array();
//構(gòu)造函數(shù)
function invoiceWordCode(invoiceCode,invoiceWordCode){
this.invoiceCode = invoiceCode;
this.invoiceWordCode = invoiceWordCode;
}
//初始化數(shù)據(jù)
<logic:iterate id="item2" name="listInfoFormBean" property="wordCodeList" indexId="i">
invoiceWordCodeArray[<bean:write name="i"/>] =
new invoiceWordCode(
'<bean:write name="item2" property="invoiceCode"/>',
'<bean:write name="item2" property="invoiceWordCode"/>');
</logic:iterate>
2.在頁(yè)面上循環(huán)顯示一個(gè)集合中的數(shù)據(jù)
<logic:iterate indexId="idx" id="sampleBean" name="sampleList">
<tr>
<td align="center" style="padding:1px 4px 0px 5px"></td><td width="150">
<bean:write property="id" name="sampleBean"/></td><td width="150">
<bean:write property="content" name="sampleBean"/></td><td width="150">
<bean:write property="creator" name="sampleBean"/></td>
</tr>
</logic-el:iterate>
id:頁(yè)面作用域bean的名稱(chēng),集合的別名
name:formbean的名字,它包含property
property:需要循環(huán)的集合的名字
logic:iterate:需要在formbean中對(duì)集合中的VO有g(shù)et\set方法
indexed=”true”:每次重復(fù)完成后集合當(dāng)前的索引