轉自: 落葉空嘆飄花翎 http://www.itpub.net/336395,1.html
Java 開發中遇到的亂碼問題
若想明白jsp開發過程中為什么會產生中文亂碼,我們先來看看unicode編碼。
Unicode (統一碼)顧名思義是一個將世界上各種文字統一在一起的東東。由美國各大電腦廠商組成的Unicode策進會來推動。目的,推廣一個世界通用的編碼體制,驚世界上所有常用的文字都涵蓋進去,從而減少個電腦商開發國外市場遇到的問題。
為了將成千上萬的文字統統收集到一個共同的編碼機制下,在兼顧經濟的原則下,不管是東方還是西方文字,每個字在Unicode中一律以兩個Bytes來表示,這樣至少有2的16次方65536種不同的組合,足以應付目前絕大多數場合的需要。
基本上,計算機只是處理數字。它們指定一個數字,來儲存字母或其他字符。在創造Unicode之前,有數百種指定這些數字的編碼系統。沒有一個編碼可以包含足夠的字符:例如,單單歐州共同體就需要好幾種不同的編碼來包括所有的語言。即使是單一種語言,例如英語,也沒有哪一個編碼可以適用于所有的字母,標點符號,和常用的技術符號。
這些編碼系統也會互相沖突。也就是說,兩種編碼可能使用相同的數字代表兩個不同的字符,或使用不同的數字代表相同的字符。任何一臺特定的計算機(特別是服務器)都需要支持許多不同的編碼,但是,不論什么時候數據通過不同的編碼或平臺之間,那些數據總會有損壞的危險。
Unicode給每個字符提供了一個唯一的數字,不論是什么平臺,不論是什么程序,不論什么語言。Unicode標準已經被這些工業界的領導們所采用,例如:Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys和其它許多公司。最新的標準都需要Unicode,例如XML, Java, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML等等,并且,Unicode是實現ISO/IEC 10646的正規方式。許多操作系統,所有最新的瀏覽器和許多其他產品都支持它。Unicode標準的出現和支持它工具的存在,是近來全球軟件技術最重要的發展趨勢。
將Unicode與客戶服務器或多層應用程序和網站結合,比使用傳統字符集節省費用。Unicode使單一軟件產品或單一網站能夠貫穿多個平臺,語言和國家,而不需要重建。它可將數據傳輸到許多不同的系統,而無損壞。
在與Unicode相關的各技術文件中,經常會看到ISO 10646和UCS這兩個名詞。
ISO是位于瑞士的國際標準局的縮寫。
UCS為ISO頒布的第10646號標準 Universal Character Set,就是世界通用字符集。
UCS通用字符集采用4個Bytes來編碼,將世界上所有的官用和商用編碼大小通吃,一網打盡。Unicode自1991年便和ISO的UCS小組密切配合,讓Unicode和ISO 10646保持一致。因此Unicode 自2.0版開始,便和 ISO 10646-1使用相同的編碼。
康熙字典中的漢字有4萬7千,如果再加上里面沒有的簡體字,和不同寫法的日文字,那么 Unicode6萬多的分配空間,光用來分配漢字就顯得捉禁見晝,更別說什么泰文,阿拉伯等其他文字了。針對這個問題Unicode和UCS采用了[中日韓文整合](CJK Unification)的解決方案,把中日韓筆畫詳盡的漢字用同一個單碼表示。
經過[中日韓文整合]的Unicode稱為統漢字Unihan。
完整的Unicode4.0版可由http://www.unicode.org/Public/UNIDATA/Unihan.txt 下載。
UTF (Unicode/UCS Transformation Format),Unicode推薦使用UTF-8和UTF-16兩種格式其中8和16指的是Bits數而不是Bytes數。
UTF-16基本就是Unicode雙字節的實現,加上一個應付未來需要的擴充編碼機制(很少用)
UTF-8 是一種不等幅的編碼方式,英數字(Ascii字碼)保持原狀,完全不受影響(因此不需要做轉換),而其他漢字資料須透過程序來轉換,會[變胖],因為每個字需要額外一個或兩個Bytes來編碼。
UCS字符集中,有UCS-2和UCS-4等編碼方式其中的2和4指的是bytes數,對應UTF-8和UTF-16.
UCS-2基本和Unicode雙byte 編碼差不多
UCS-4四 byte編碼表示一個字,在每個 UCS-2前面加上兩個空白的Byte,便可得到對應的 UCS-4。
Unicode的空間分配:
以下Unicode區位碼均以16進制表示
Unicode的前256個字符和ISO-8859-1(西歐字母)完全相同,其中前半段就是Ascii(u+0000到u+00FF)。每個ISO-8859-1碼前面補上一個空byte(0x00)后才是相應的Unicode碼。
和我們切身相關的Unihan主要分布在u+3400到u+F9FFF之間,GB2312和BIG5主要分布在u+4E00到U+9FFF之間。
UTF-8的編碼原理和特性:
知道了西歐字符和漢字在Unicode中的位置后,來看看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(下劃線空位)是否足以用來代表區位中各Unicode碼,剛好夠用。
那么當程序處理UTF-8編碼文件時,如何得知一個字符的疆界落在哪里?還有到底他是以三種形式那一中出現呢?
每個以UTF-8編碼的字符,不管是以一、二、三個bytes出現,第一個byte前端都清楚地標示了該字符的byte總數。如110種有兩個1,代表這種字符是以第二種方式出現,由兩個bytes組成。而1110有三個1,表示這種字符一點種方式出現,由三個字節組成。
每個多重byte的UTF-8編碼有一個共同的通性,即其中的第二個第三個byte, 一律以10兩個bits開頭。由于其中的最高位總設成1,可以很容易和那些在UTF-8中只用一個Byte的ASCII字元區分開來,方便偵錯。
因為上述設計特點,UTF-8和Unicode之間,可以很容易做雙向自由轉換,而不會丟失任何資料。
解決辦法:亂碼問題在 NT操作系統我沒怎么碰到過,但是在UNIX 或LINUX系統上出現的比較多
由于操作系統和使用環境不一樣,產生亂碼的方式也不一樣,但是如果掌握了上面的Unicode 編碼原理,自己仔細分析一下,很多問題便可迎刃而解。
下面看看幾個常見的例子。
1. 如果一些網站服務器例如Tomcat 如果遇到中文亂碼問題,可以修改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 設成GBK或GB2312
2. 表單中或傳遞字符串:本來輸入的漢字是正常的,但是提交后再顯示出來是亂碼,因為提交的一般是 ISO8859編碼,所以顯示的時候要轉成GB2312編碼:
String S=new String(rs.getString("news").getBytes("gb2312"),"ISO8859_1");
//rs為待轉換的字符串
然后使用S字符串的值就可以了
3. 有的服務器端的語言環境如果設成簡體中文的也可以解決此類問題
4. 插入數據庫中的字符是亂碼
看看數據庫中支持的是何種編碼方式,用類似2中的方式作一下轉換即可。
5. 總之,用jsp開發,碰到亂碼,你得分析是讀的時候發生亂碼,還是寫的時候發生亂碼,用2中的轉換,基本就能解決問題,有些時候寫的時候做一次轉換,例如:
String S=new String(rs.getString("news").getBytes("gb2312"),"ISO8859_1");
//讀的時候在轉換回來
String S=new String(rs.getString("news").getBytes("ISO8859_1"),"GB2312");
或者把ISO8859-1和GB2312 的位置換一下,自己多試試,就能找到解決問題的辦法。
Java_struts 入門快速手冊
----by omencathay
Struts
簡介
1、 Struts基于MVC模式 Model(Bean) ,View(jsp文件), Control (Action類,ActionForm類)
2、 開發準備
struts http://jakarta.apache.org/struts
jdk1.2版本以上 http://java.sun.com/j2se
Xerces XML parser http://xml.apache.org/xerces-j
下載struts后,解壓zip文件到一個臨時目錄;然后拷貝struts.jar, jakarta-oro.jar, jdbc2_0-stdext.jar和common*.jar文件到你所應用struts的WEB-INF/lib目錄下;拷貝struts*.tld文件和*.dtd文件到WEB-INF目錄下,確定該才提到的所有的jar包都在web應用服務器的 classpath環境變量上設置。
3、 配置 (兩個xml文件:web.xml, struts-config.xml)
配置web.xml,第一件事情就是注冊組件action servlet,<servlet> .. </servlet>標簽封裝了整個struts 框架的應用程序
<!-- 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>
每個<action>元素定義了特定的功能與相關聯的動作類, 大多數action元素至少包括以下三個部分。
Path-----應用程序映射的路徑
Type-----需要的完整的包和類
Name-----action應用的<form-bean>元素的名稱
;
<forward>標簽告訴struts框架將要跳轉到哪個jsp頁面;
<data-sources>標簽給出數據源屬性;
4、 struts核心標簽庫示例
1. Html:form
屬性:onsubmit
onsubmit屬性得到的是:表單提交時的javaScript事件句柄
用法:
(1).
Onsubmit 和 html:submit配合使用,javaScript函數返回true或false
<html:form action=”” onsubmit=”return javaScriptFunction();”>
和
<html:submit onclick=” javaScriptFunction();”/>
配合使用
在javaScriptFunction(){
}中加入return true和return false
html:from 根據返回的true或者false決定是否提交
等同于
(2)。
使用Html:button 要在javaScript函數中加入form.submit();
<html:form action=””>
<html:button onclick=” javaScriptFunction();”/>
form.submit();決定表單的提交
2. Html:text
Html:text是輸入框,可以修改數據做為property的值
如果要修改的屬性在bean中有get\set方法,可以寫為
<html:text name="listInfoFormBean" property="invoiceCode"/>
如果要修改的屬性在某一個VO里,在VO里對這一屬性有get\set方法,在bean里對這一VO有get\set方法,可以寫為:
<html:text name="listInfoFormBean" property="tbInvStoresVO.invoiceCode"/>
3. Bean:write
Bean:write與html:text用法相似。只是bean:write輸出的數據是readonly的
這一點可以在html:text中加入屬性 readonly=”true”來實現
4. Html:select
<html:select property="invoicePurchaseCode" name=”beanname”>
<option value="0">----</option>
<option value="1">驗舊供新</option>
<option value="2">交舊供新</option>
<option value="3">批量供應</option>
</html:select>
name::bean的名稱。如果沒有設置,將適用于這個內嵌表單相關的formbean的名字
property:表單提交是送回的請求參數的名字,也是用來確定哪個屬性被選中的bean的屬性的名字
value:用來表明需要被選中的選項
怎么生成一個select:
option.options = new(value, lablename)
5. logic:iterate
logic:iterate的兩個用法
1. 在javaScript中初始化數組數據
//聲明數組
var invoiceWordCodeArray = new Array();
//構造函數
function invoiceWordCode(invoiceCode,invoiceWordCode){
this.invoiceCode = invoiceCode;
this.invoiceWordCode = invoiceWordCode;
}
//初始化數據
<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.在頁面上循環顯示一個集合中的數據
<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:頁面作用域bean的名稱,集合的別名
name:formbean的名字,它包含property
property:需要循環的集合的名字
logic:iterate:需要在formbean中對集合中的VO有get\set方法
indexed=”true”:每次重復完成后集合當前的索引