版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、PRIMETON TECHNOLOGIES, LTD.上海普元信息技術(shù)有限責(zé)任公司不同情況下的亂碼處理方案經(jīng)驗技巧總結(jié)No part of this document may be reproduced, stored in any electronic retrieval system, or transmitted in any form or by any means, mechanical, photocopying, recording, otherwise, without the written permission of the copyright owner.COPYRIGH
2、T 2006 by Primeton Technologies, Ltd. ALL RIGHTS RESERVED.文檔修訂記錄序號版本號修訂日期修訂概述修訂人審批人備注10.12006-11-20創(chuàng)建林地發(fā)規(guī)范及約定1. 【規(guī)范及約定】的內(nèi)容僅僅是對本文檔編寫的規(guī)范和約定進行描述,文檔編寫人員必須嚴(yán)格按照本規(guī)范和約定進行編寫,在文檔正式發(fā)布時刪除該部分內(nèi)容;2. 文檔內(nèi)容采用“首行縮進、小四號字體、1.5倍行距”的格式,選中段落文本使用快捷鍵【Ctrl+Alt+4】可以進行格式化(直接選中藍(lán)色的說明文字即可);3. 必須填寫“文檔修訂控制記錄”;4. 文檔目錄必須更新為最新的,與實際內(nèi)容相對
3、應(yīng);5. 模版中每部分內(nèi)容的下面的藍(lán)色字體是對這塊內(nèi)容的說明,編寫文檔時選中這段文字,使用【Ctrl+Alt+4】快捷鍵即可格式化成要求的字體; 1 文檔摘要1.1 文檔分類經(jīng)驗技巧-常見問題級、常見問題-運行、FAQ-EOS Server1.2 關(guān)鍵字/Tag亂碼、EOS、WebSphere、配置文件、分界點、轉(zhuǎn)碼、字符集1.3 摘要本文檔是針對我們遇到亂碼問題的經(jīng)驗總結(jié),同時,列出了EOS+WebSphere5.1環(huán)境下經(jīng)常遇到過得亂碼問題的解決過程1.4 作者、協(xié)作者及評審人員作者、寫作者:林地發(fā)、華石新評審人員:初評小組、劉國鵬1.5 定義、首字母縮寫詞及縮略語隱含提交: jsp文件中
4、通過引用/fbtools/page/hiddensubmit.js,將客戶端的請求通過ajax提交到fbtoolspagehiddensubmit.jsp來獲取服務(wù)器端數(shù)據(jù)2 簡介2.1 場景描述在瀏覽器界面上出現(xiàn)亂碼、出現(xiàn)“?”、出現(xiàn)解析XML錯誤、js腳本錯誤2.2 適用環(huán)境EOS5.X+WebSphere5.x3 經(jīng)驗總結(jié)3.1 解決思路亂碼是應(yīng)用系統(tǒng)運行中經(jīng)常出現(xiàn)的一個問題,也是應(yīng)用系統(tǒng)中非常突出而且必須解決的一個問題。由于引起出現(xiàn)亂碼的因素很多,所以解決亂碼問題比較復(fù)雜。本文從編碼原理到實際案例對亂碼原因進行詳細(xì)的分析,并且整理和歸納了多個項目出現(xiàn)亂碼現(xiàn)象的解決經(jīng)驗,總結(jié)了解決一般性
5、亂碼的辦法和過程。在整個B/S請求從客戶端頁面提交內(nèi)容到服務(wù)器,服務(wù)器接收響應(yīng),并從數(shù)據(jù)庫中獲取數(shù)據(jù),經(jīng)過一番處理之后再返回給客戶端的瀏覽器頁面顯示的過程中,只要一個環(huán)節(jié)在轉(zhuǎn)碼過程中有錯誤就會導(dǎo)致亂碼的現(xiàn)象發(fā)生。如果你的系統(tǒng)出現(xiàn)了亂碼,首先不要著急,不要被系統(tǒng)中出現(xiàn)的問題所嚇壞。如果出現(xiàn)了這種問題又該如何辦呢?我們應(yīng)該先判斷亂碼的現(xiàn)象,要根據(jù)現(xiàn)象,查出數(shù)據(jù)在整個數(shù)據(jù)流向的過程中,數(shù)據(jù)到底從什么時候什么地方開始由正常開始變?yōu)閬y碼,即找出數(shù)據(jù)變成亂碼的分界點:Ø 如果是數(shù)據(jù)庫中的數(shù)據(jù)本身是亂碼,需要檢查數(shù)據(jù)庫的字符集是否設(shè)置正確,不同的數(shù)據(jù)庫不一樣比如Oracle數(shù)據(jù)庫在安裝的過程中就可
6、以選擇某種字符集:ALTER DATABASE CHARACTER SET ZHS16GBK查找當(dāng)前字符集:select userenv('language') from dual;DB2在創(chuàng)建數(shù)據(jù)庫的時候可以指定字符集:create database sccrm using codeset UTF-8 territory CNMySQL在創(chuàng)建數(shù)據(jù)庫的時候可以指定字符集:create database testxxx default charset=UTF-8Ø 操作系統(tǒng)是否安裝相應(yīng)的字符集(unix下可以用locale查看當(dāng)前字符集),將相應(yīng)的數(shù)據(jù)打印出來即可
7、16; Java程序是否存在轉(zhuǎn)碼錯誤,字符集經(jīng)常是在UTF-8、GBK、ISO-8859-1之間轉(zhuǎn)換Ø 應(yīng)用服務(wù)器各個相關(guān)設(shè)置字符集的地方是否設(shè)置正確找到分界點之后,針對分界點之前和之后,查找在什么地方可以設(shè)置字符集,每一個分界點可以在哪些地方設(shè)置相關(guān)的字符集。如果是程序,可以查找到哪一行代碼獲取數(shù)據(jù)的時候開始亂碼,從而可以考慮修改代碼。如果不是程序,需要查看當(dāng)前應(yīng)用有哪些地方可以設(shè)置字符集,并且要了解每個設(shè)置字符集的地方,他們之間的相互關(guān)系3.2 編碼轉(zhuǎn)換的關(guān)鍵點常見亂碼現(xiàn)象:Ø 瀏覽器中看到的 Jsp/Servlet 頁面中的漢字變成成了 ?Ø 瀏覽器中看到的
8、 Servlet 頁面中的漢字變成成了亂碼 Ø Jsp/Servlet 頁面無法顯示 GBK 漢字Ø JSP 頁面中內(nèi)嵌在<%.%>,<%=.%>等Tag包含的 JAVA code 中的中文成了亂碼,但頁面的其它漢字是對的Ø Jsp/Servlet 不能接收 form 提交的漢字Ø JSP/Servlet 數(shù)據(jù)庫讀寫無法獲得正確的內(nèi)容隱藏在這些問題后面的是各種錯誤的字符轉(zhuǎn)換和處理,是因為 Java font 設(shè)置錯誤引起的。解決類似的字符 encoding 問題,需要了解 Jsp/Servlet 的運行過程,檢查可能出現(xiàn)問題的各個
9、點。 根據(jù)如上圖表,我們可以得出編碼轉(zhuǎn)換點如下:Ø JSP 編譯:Java 應(yīng)用服務(wù)器將根據(jù) JVM 的 值讀取 JSP 源文件,編譯生成 JAVA 源文件,再根據(jù) 值寫回文件系統(tǒng)。如果當(dāng)前系統(tǒng)語言支持 GBK,那么這時候不會出現(xiàn) encoding 問題。如果是英文的系統(tǒng),如 LANG 是 en_US 的 Linux, AIX 或 Solaris,則要將 JVM 的 值置成 GBK 。系統(tǒng)語言如果是 GB2312,則根據(jù)需要,確定要不要設(shè)置 ,將 設(shè)為 GBK 可以解決潛在的 GBK 字符亂碼問題Ø Java 需要被編譯為 .class 才能在 JVM 中執(zhí)行,這個過程存在
10、同樣的 問題。從這里開始 servlet 和 jsp 的運行就類似了,只不過 Servlet 的編譯不是自動進行的。對于JSP程序, 對產(chǎn)生的JAVA 中間文件的編譯是自動進行的(在程序中直接調(diào)用sun.tools.javac.Main類). 因此如果在這一步出現(xiàn)問題的話, 也要檢查encoding和OS的語言環(huán)境,或者將內(nèi)嵌在JSP JAVA Code 中的靜態(tài)漢字轉(zhuǎn)為 Unicode, 要么靜態(tài)文本輸出不要放在 JAVA code 中。對于Servlet, javac 編譯時手工指定-encoding 參數(shù)就可以了。Ø Servlet 需要將 HTML 頁面內(nèi)容轉(zhuǎn)換為 brows
11、er 可接受的 encoding 內(nèi)容發(fā)送出去。依賴于各 JAVA App Server 的實現(xiàn)方式,有的將查詢 Browser 的 accept-charset 和 accept-language 參數(shù)或以其它可能的方式確定 encoding 值,有的則不管。因此采用固定encoding 也許是最好的解決方法。對于中文網(wǎng)頁,可在 JSP 或 Servlet 中設(shè)置 contentType="text/html; charset=GB2312";如果頁面中有GBK字符,則設(shè)置為contentType="text/html; charset=GBK",由于
12、IE 和 Netscape對GBK的支持程度不一樣,作這種設(shè)置時需要測試一下。因為16位 JAVA char在網(wǎng)絡(luò)傳送時高8位會被丟棄,也為了確保Servlet頁面中的漢字(包括內(nèi)嵌的和servlet運行過程中得到的)是期望的內(nèi)碼,可以用 PrintWriter out=res.getWriter() 取代 ServletOutputStream out=res.getOutputStream(). PrinterWriter 將根據(jù)contentType中指定的charset作轉(zhuǎn)換 (ContentType需在此之前指定!); 也可以用OutputStreamWriter封裝 Servlet
13、OutputStream 類并用write(String)輸出漢字字符串。對于 JSP,JAVA Application Server 應(yīng)當(dāng)能夠確保在這個階段將嵌入的漢字正確傳送出去。Ø 解釋 URL 字符 encoding也有可能出現(xiàn)亂碼。如果通過 get/post 方式從 browser 返回的參數(shù)值中包含漢字信息, servlet 將無法得到正確的值。URL傳值為瀏覽器客戶端按iso-8859-1進行傳輸,服務(wù)器可以設(shè)置-Ddefault.client.encoding=GBK,那么URL傳輸中文時可以不再指定編碼而直接可以得到客戶端傳輸?shù)闹形淖址?#216; JSP/Ser
14、vlet 編程中經(jīng)常出現(xiàn) encoding 問題的另一個地方是讀寫數(shù)據(jù)庫中的數(shù)據(jù)。流行的關(guān)系數(shù)據(jù)庫系統(tǒng)都支持?jǐn)?shù)據(jù)庫 encoding,也就是說在創(chuàng)建數(shù)據(jù)庫時可以指定它自己的字符集設(shè)置,數(shù)據(jù)庫的數(shù)據(jù)以指定的編碼形式存儲。當(dāng)應(yīng)用程序訪問數(shù)據(jù)時,在入口和出口處都會有 encoding 轉(zhuǎn)換。對于中文數(shù)據(jù),數(shù)據(jù)庫字符編碼的設(shè)置應(yīng)當(dāng)保證數(shù)據(jù)的完整性. GB2312,GBK,UTF-8 等都是可選的數(shù)據(jù)庫 encoding;也可以選擇 ISO8859-1 (8-bit),那么應(yīng)用程序在寫數(shù)據(jù)之前須將 16Bit 的一個漢字或 Unicode 拆分成兩個 8-bit 的字符,讀數(shù)據(jù)之后則需將兩個字節(jié)合并起來
15、。沒有充分利用數(shù)據(jù)庫 encoding 的作用,反而增加了編程的復(fù)雜度,ISO8859-1不是推薦的數(shù)據(jù)庫 encoding。JSP/Servlet編程時,可以先用數(shù)據(jù)庫管理系統(tǒng)提供的管理功能檢查其中的中文數(shù)據(jù)是否正確。然后應(yīng)當(dāng)注意的是讀出來的數(shù)據(jù)的 encoding,JAVA 程序中一般得到的是 Unicode。寫數(shù)據(jù)時則相反。3.3 定位問題時常用的技巧定位中文encoding問題通常采用最笨的也是最有效的辦法在你認(rèn)為有嫌疑的程序處理后打印字符串的內(nèi)碼。通過打印字符串的內(nèi)碼,你可以發(fā)現(xiàn)什么時候中文字符被轉(zhuǎn)換成Unicode,什么時候Unicode被轉(zhuǎn)回中文內(nèi)碼,什么時候一個中文字成了兩個
16、Unicode 字符,什么時候中文字符串被轉(zhuǎn)成了一串問號,什么時候中文字符串的高位被截掉了取用合適的樣本字符串也有助于區(qū)分問題的類型。如:”aa啊aa?aa” 等中英相間、GB、GBK特征字符均有的字符串。一般來說,英文字符無論怎么轉(zhuǎn)換或處理,都不會失真(如果遇到了,可以嘗試著增加連續(xù)的英文字母長度)3.4 WEBSPHERE字符集相關(guān)配置有兩種字符集編碼問題值得注意:一、Request/Response 字符集- HTTP接收、發(fā)送的參數(shù)的字符集,例如從表單中和從JSP網(wǎng)頁中提交的內(nèi)容二、JSP網(wǎng)頁編碼- JSP文件本身的編碼因為很多人都混淆這兩種編碼問題,而且被什么參數(shù)影響什么編碼所迷惑。
17、下表是總結(jié)參數(shù)影響編碼轉(zhuǎn)換的各種情況Request/Response字符編碼JSP文件編碼WebSphereV5.X(JSP1.2Servlet2.3)Extension enabled擴展方式1.隱式設(shè)置l client.encoding.overridel Eperties(default)3.文件編碼l pageEncodingl contentType l (default)Extension disabled(default)默認(rèn)非擴展方式2.顯式設(shè)置Servletl setChareacterEncoding()(request)l setContentTyp
18、e()(response)JSPl setCharacterEndcoding()(request)l contentType (response)3.4.1 設(shè)置Request/Response 編碼通常,從表單中發(fā)送的request參數(shù)是以form本身的同樣的編碼進行編碼的。也就是說request和response編碼是相同的。這些編碼能夠決定隱式和顯式的設(shè)置方式。Websphere實現(xiàn)隱式設(shè)置方式去幫忙開發(fā)全球的應(yīng)用。有了隱式設(shè)置方式,英文版的應(yīng)用運行在中文版本下就無須任何代碼上改動。而且Websphere也提供顯式設(shè)置方式去保持與其它應(yīng)用的兼容。哪一種方式更適合應(yīng)用本身由設(shè)計者自己決定
19、。隱式設(shè)置方式Websphere的全球化擴展。Websphere有內(nèi)置的能力去減化全球化版本的開發(fā)。它隱式的提供了根據(jù)accept-language HTTP協(xié)議頭進行字符集轉(zhuǎn)換的功能。這是websphere能夠幫助你開發(fā)全球版本的重要原因之一。WAS_HOME/properties/EpertiesWebshpere決定了request/response的編碼,在分析客戶輸入的值時用getparameter和writing輸出的時候跟據(jù)accpt-language值。這個語言值(accept-language)和編碼名稱與perties關(guān)聯(lián)。如下
20、圖Eperties文件示例如下:其它應(yīng)用服務(wù)器可能只支持iso-8859-1編碼。并且如果你想支持其它語言,你可能不得不在每個servlet中包含一個特殊處理的代碼設(shè)置擴展方式注意,在webshpere中默認(rèn)為非擴展方式。如果要設(shè)置為擴展方式,你不得不把autoRequestEncoding 和autoResponseEncoding設(shè)置為真,在ibm-web-ext.xmi文件中如下圖: Client.encoding.override也有可能在某些情況下,你想覆蓋perties中的設(shè)置,當(dāng)你想用UTF-8在整個系統(tǒng)當(dāng)中,在JVM中設(shè)置系統(tǒng)屬性c
21、lient.encoding.override,設(shè)置-Dclient.encoding.override=UTF-8為通常的JVM參數(shù)注意,編輯perties將影響在Websphere系統(tǒng)中的所有的應(yīng)用。而client.encoding.override只影響當(dāng)前相關(guān)的應(yīng)用服務(wù)顯式設(shè)置方式 標(biāo)準(zhǔn)方式(非擴展方式)當(dāng)你想用Websphere的擴展功能時,你可方便的采用隱式設(shè)置。如果你想兼容其它系統(tǒng),你可“顯式”的覆蓋環(huán)境設(shè)置去支持你想要的編碼。在這樣的情況下,你不得不在代碼層面指明編碼,并且進行顯式的轉(zhuǎn)換Servlet你可以告訴你的容器你想在servletAPI中應(yīng)用什么編
22、碼,setCharacterEncoding( ) and setContentType( ),通過這些API你可以顯式的設(shè)置編碼。setCharacterEncoding()能用在WASV5版本之上。在做這樣之前你必須調(diào)用getParameter()之前調(diào)用setCharacterEncoding(), setContentType()必須在調(diào)getWriter()之前。下面為代碼示例:<HTML><HEAD><META http-equiv="Content-Type" content="text/html; charset=UT
23、F-8"><TITLE>Sending input to Server</TITLE></HEAD><BODY><H1>Input your name and push send</H1><FORM action="/apg/FormServlet" method="POST"><INPUT type="text" name="param"><INPUT type="submit"
24、; name="submit" value="Send"></FORM></BODY></HTML>form.html提交內(nèi)容到FormServletJava Server Pages (JSP) 在JSP里,contentType能夠用于指定輸出的HTML編碼。<% page language="java" contentType="text/html; charset=UTF-8"%>下面的代碼可以實現(xiàn)。JSP創(chuàng)建了輸出的HTML在charset中指明了co
25、ntentType頁面。你應(yīng)該總是設(shè)置編碼,因為這樣可以為每個JSP指明自己的編碼。3.4.2 JSP頁面編碼JSP是動態(tài)的編譯成為Java字節(jié)碼的,Java字節(jié)碼的存儲方式為Unicode(UTF-8),而且從JSP的頁面編碼到Unicode是必要的。Java編譯器通過contentType頁面指寫編碼,所以在編碼JSP代碼中要指定contentType。這個參數(shù)同時還用于指定輸出的編碼。而且這兩個編碼是一樣的。這種設(shè)計減少編碼問題。pageEncoding也有可能,JSP的編碼和輸出的編碼是不同的。這種情況下,pageEncoding可以用于指明JSP文件的編碼。<% page la
26、nguage="java" contentType="text/html; charset=UTF-8" pageEncoding="Shift_JIS" %>defaultEncoding如果所有的JSP都以同樣的編碼,那么設(shè)置defaultEncoding在ibm-web-ext.xmi中是一個好的辦法。那么JSP中就可無須設(shè)置contentType值。下如是決定頁面編碼的順序:· The JSP page's contentType directive's charset. · The
27、defaultEncoding parameter's value. · The value of the system property (default) 是系統(tǒng)屬性,它指明了當(dāng)前java環(huán)境的字符編碼,例如你的服務(wù)器運行在中文環(huán)境下,。因為這個值取決于運行系統(tǒng),你應(yīng)該設(shè)置其它編碼方式,不推薦使用值做為頁面的編碼設(shè)置。3.5 WEBLOGIC字符集相關(guān)配置WebLogic Server 中 I18n 的主要特性:§ 在 WebLogic Server 內(nèi)部,所有字符都按 Unicode 進行處理。只要輸入或輸出字符數(shù)據(jù),就執(zhí)行代碼轉(zhuǎn)換。 § 必須分別為
28、 WebLogic Server、J2EE 組件和 WebLogic Server 容器上的資源指定適當(dāng)?shù)木幋a轉(zhuǎn)換。 § 如果不指定編碼轉(zhuǎn)換,系統(tǒng)將應(yīng)用默認(rèn)的編碼轉(zhuǎn)換。 與 JSP/Servlet 有關(guān)的編碼設(shè)置包括§ 從 Servlet 輸出的 HTTP 響應(yīng)中使用的寫入器編碼 § JSP 文件的編碼 § 從 JSP 輸出的寫入器編碼 § HTTP 請求(如 GET/POST)的編碼(對于特定的請求 URL) § 數(shù)據(jù)(如 GET/POST)的編碼(對于特定的 HTTP 請求) § JSP 容器的編碼 § Jav
29、a 編碼和 IANA 字符集之間的映射 如果指定了多個參數(shù),可以通過一組特定的規(guī)則來確定哪個參數(shù)有效。例如,如果 UTF-8 設(shè)置為 JSP 容器的默認(rèn)編碼,但在特定 JSP 的 page 標(biāo)記中指定了 GB2312,則將使用 GB2312。一般來說,在較小范圍中指定的編碼具有較高的優(yōu)先級。如有必要,可以在較大的范圍中設(shè)置默認(rèn)編碼,并在較小的范圍中設(shè)置特殊編碼。建議您在整個應(yīng)用程序中使用同一種編碼。使用簡體中文的一般步驟如上所述,WebLogic Server 提供一組用來指定編碼的參數(shù)。在使用它時,必須指定從 HTTP 請求到 HTTP 響應(yīng)的所有內(nèi)容。在默認(rèn)情況下,將使用 ISO-8859
30、-1 編碼。3.5.1 Servlet1. 指定 HTTP 響應(yīng)的編碼 - response.setContentType() 2. 指定瀏覽器顯示的編碼 - HTML Content-Type 3. 指定 HTTP 請求的編碼 - request.setCharacterEncoding 或 <input-charset>指定 HTTP 響應(yīng)的編碼方法為 response.setContentType(),要為由 Servlet 生成的 HTML 頁面指定編碼,請使用 setContentType() 方法。對 setContentType() 的調(diào)用指定下列內(nèi)容:§
31、用于響應(yīng)的 HTTP 頭中的 ContentType 特性 § 用于輸出響應(yīng)的寫入器編碼 因此,在獲得寫入器之前,必須先調(diào)用 setContentType()。res.setContentType("text/html;charset=GB2312");PrintWriter out = res.getWriter();該調(diào)用指定 HTTP 頭中的 contentType。這意味著同時指定了瀏覽器顯示的編碼。指定 HTTP 請求的編碼 - request.setCharacterEncoding 或 <input-charset>現(xiàn)在,您已經(jīng)指定了 H
32、TTP 響應(yīng)(使用上述方法從 WebLogic Server 發(fā)送到客戶端的數(shù)據(jù))的編碼設(shè)置。下面描述了在將數(shù)據(jù)從客戶端發(fā)送到 WebLogic Server 時,如何設(shè)置 HTTP 請求的編碼。可通過三種方法指定 HTTP 請求的編碼:§ 將字符集寫入 HTTP 請求的 contentType 中 此方法最符合 HTTP 規(guī)范。但是,不能在 Microsoft Internet Explorer 或 Netscape 瀏覽器中指定該值。§ 在服務(wù)器上指定 HTTP 請求的編碼 使用 request.setCharacterEncoding() 方法??梢灾付總€請求的編碼
33、。還可以執(zhí)行更細(xì)化的操作(如動態(tài)控制編碼)。另外,setCharacterEncoding() 符合 Servlet 2.3 規(guī)范。因此,可以實現(xiàn)應(yīng)用程序可移植性。request.setCharacterEncoding("GB2312");String pval = request.getParameter(pname);§ 使用 Web 應(yīng)用程序部署描述符 (weblogic.xml) 中的 <input-charset>,指定請求 URL 的編碼。 在 WebLogic Server 6.0 中,它在 web.xml 中進行設(shè)置。在 WebLog
34、ic Server 6.1 或更高版本中,它在 weblogic.xml 中進行設(shè)置。同時,元素名稱等也進行了更改。因此,如果從 WebLogic Server 6.0 遷移,需要修改 weblogic.xml 和 web.xml 文件。對于從客戶端 Web 瀏覽器的請求 URL 中指定的資源,<input-charset> 的值確定該資源的路徑在服務(wù)器端的編碼。示例:§ Obtain in UTF-8 § Obtain in GB2312 系統(tǒng)允許使用這些配置??梢园慈缦滤久枋?<input-charset>。目標(biāo) Web 應(yīng)用程序的 <c
35、harset-params> 元素應(yīng)當(dāng)寫在部署描述符 (weblogic.xml) 文件中。在 <charset-params>(內(nèi)嵌于 <weblogic-web-app>)中,寫入要為其指定編碼的請求 URL 路徑,以及要為 HTTP 請求指定的編碼(用 IANA 名稱)。有關(guān) Java 編碼名稱和 IANA 字符集之間映射的信息,請參閱“Java 編碼和 IANA 字符集之間的映射(在 weblogic.xml 中設(shè)置)”部分。下面是一個處理多個編碼的 Web 應(yīng)用程序的示例。在本例中,“/*”的編碼設(shè)置為 UTF-8,“/rus/jo/*”的編碼設(shè)置為 G
36、B2312。<charset-params> <input-charset> <resource-path>/*</resource-path> <java-charset-name>UTF-8</java-charset-name> </input-charset></charset-params><charset-params> <input-charset> <resource-path>/rus/joe/*</resource-path> &l
37、t;java-charset-name>GB2312</java-charset-name> </input-charset></charset-params>3.5.2 JSP1. 指定 JSP 文件的編碼 - page 標(biāo)記中的 pageEncoding 指令(可選) 2. 指定頁面輸出的編碼 - page 標(biāo)記中的 contentType 指令 3. 指定瀏覽器顯示的編碼 - HTML Content-Type 4. 指定 HTTP 請求的編碼 - request.setCharacterEncoding 或 <input-charset&
38、gt;指定 JSP 文件的編碼 - pageEncoding(可選)要指定 WebLogic Server JSP 容器或 JSP 編譯器用來讀取 JSP 文件的編碼,請在 page 標(biāo)記中指定 pageEncoding 指令,如下所示:<% page contentType="text/html; charset=GB2312" pageEncoding="GB2312" %>指定頁面輸出的編碼 - page 標(biāo)記中的 contentType 指令要指定頁面輸出的編碼,請在 page 標(biāo)記中指定 contentType 指令,如下所示:&l
39、t;% page contentType="text/html; charset=GB2312" %>另外,當(dāng)您在 page 指令中指定 contentType 時,會在 HTTP 響應(yīng)的 HTTP 頭中指定同樣的 contentType,這意味著同時指定了瀏覽器顯示的編碼。如果未設(shè)置 pageEncoding 指令,會將 contentType 指令用作讀取 JSP 文件的編碼。如果 JSP 容器找到 contentType 設(shè)置,會停止解析 JSP 文件,將文件讀取器切換到這個新指定的編碼,重新從頭解析 JSP 頁。如果在一個文件中指定了多個 contentTyp
40、e,就會出現(xiàn)解析錯誤。因此,使用靜態(tài)包含將一個文件包含在另一個文件中時,如果這兩個文件都有各自的編碼規(guī)范,就會出現(xiàn)錯誤。在動態(tài)包含中,不會出現(xiàn)錯誤,但是將生成亂碼字符。注意:如果在一個文件中發(fā)現(xiàn)多個 contentType 實例,這兩個實例都使用相同的值,則是有效的,不會導(dǎo)致解析錯誤。(有關(guān)詳細(xì)信息,請參閱靜態(tài)與動態(tài)包含以及編碼差異)。<jsp-param> <param-name>backwardCompatible</param-name> <param-value>true</param-value></jsp-param
41、>例如,當(dāng)使用靜態(tài)包含 (<% include) 執(zhí)行包含操作時,如果“包含源”和“包含目標(biāo)”都有各自的 page 指令,并且一個轉(zhuǎn)換單元有多個 page 指令,則只要每個 page 指令都指定相同的編碼,就不會發(fā)生任何問題。指定 HTTP 請求的編碼可以像在 Servlet 中一樣,在 JSP 中指定 HTTP 請求的編碼。有關(guān)詳細(xì)信息,請參閱 Servlet 部分。<% request.setCharacterEncoding("GB2312"); String pval = request.getParameter(pname); %>3.6
42、字符集轉(zhuǎn)換流程轉(zhuǎn)換流程圖客戶端JSP文件JAVA文件數(shù)據(jù)庫文件存儲Class文件ServletGB2312UTF-8unicodeunicode服務(wù)器指定瀏覽器指定GB2312GB2312UTF-8UTF-8一、JAVA文件編譯成Class文件過程的編碼問題 JDK中與中文相關(guān)的編碼列表編碼名稱說明ASCII7位,與ascii7相同ISO8859-18-位,與 8859_1,ISO-8859-1,ISO_8859-1,latin1.等相同GB2312-8016位,與gb2312,gb2312-1980,EUC_CN,euccn,1381,Cp1381, 1383, Cp1383, ISO202
43、2CN,ISO2022CN_GB.等相同GBK與MS936相同,注意:區(qū)分大小寫UTF8與UTF-8相同GB18030與cp1392、1392相同,目前支持的JDK很少Java源程序中的字符一般以UNICODE編碼存儲,在編譯過程轉(zhuǎn)換成相應(yīng)的UTF-8編碼。二、JSP文件動態(tài)編譯成Servlet的的編碼問題Jsp的源文件是以“.jsp”結(jié)尾的文本文件。在本節(jié)中,將闡述JSP文件的解釋和編譯過程,并跟蹤其中的中文變化。1、JSP/Servlet引擎提供的JSP轉(zhuǎn)換工具(jspc)搜索JSP文件中用% page contentType ="text/html; charset=Jsp-c
44、harset"%中指定的charset。如果在JSP文件中未指定Jsp-charset,則取JVM中的默認(rèn)設(shè)置,一般情況下,這個值是ISO8859-1;2、jspc用相當(dāng)于“javac encoding Jsp-charset”的命令解釋JSP文件中出現(xiàn)的所有字符,包括中文字符和ASCII字符,然后把這些字符轉(zhuǎn)換成Unicode字符,再轉(zhuǎn)化成UTF格式,存為JAVA文件。ASCII碼字符轉(zhuǎn)化為Unicode字符時只是簡單地在前面加“00”,如“A”,轉(zhuǎn)化為“u0041”(不需要理由,Unicode的碼表就是這么編的)。然后,經(jīng)過到UTF的轉(zhuǎn)換,又變回“41”了!這也就是可以使用普通文
45、本編輯器查看由JSP生成的JAVA文件的原因3、引擎用相當(dāng)于“javac encoding UNICODE”的命令,把JAVA文件編譯成CLASS文件三、JDBC與數(shù)據(jù)庫數(shù)據(jù)交換時的編輯問題在JAVA運行期時,內(nèi)容交換的編碼為unicode編碼,JDBC接收到的字符流必須是合法的編碼格式,然后由JDBC向數(shù)據(jù)庫提交數(shù)據(jù)請求。JSP/Servlet 編程中經(jīng)常出現(xiàn)編碼問題,除了上述討論的方面,另方面是讀寫數(shù)據(jù)庫中的數(shù)據(jù)。目前業(yè)界常用的關(guān)系數(shù)據(jù)庫系統(tǒng)都支持?jǐn)?shù)據(jù)庫多語言編碼,也就是說在創(chuàng)建數(shù)據(jù)庫時可以指定它自己的字符集設(shè)置,數(shù)據(jù)庫的數(shù)據(jù)就將以指定的編碼形式存儲。當(dāng)應(yīng)用程序訪問數(shù)據(jù)時,在入口和出口處都
46、會有 encoding 轉(zhuǎn)換。對于中文數(shù)據(jù),數(shù)據(jù)庫字符編碼的設(shè)置應(yīng)當(dāng)保證數(shù)據(jù)的完整性。GB2312、GBK、UTF-8、ISO-8859-1等都是可選的數(shù)據(jù)庫編碼。但是如果編碼設(shè)置成了ISO-8859-1,則應(yīng)用程序在寫數(shù)據(jù)之前須將 16Bit 的一個漢字或 Unicode 拆分成兩個 8-bit 的字符,讀數(shù)據(jù)之后則需將兩個字節(jié)合并起來,同時還要判別其中的 SBCS 字符。這種情況沒有充分利用數(shù)據(jù)庫編碼的作用,反而增加了編程的復(fù)雜度。因此ISO-8859-1不是推薦的數(shù)據(jù)庫編碼。針對上述狀況,下列代碼示例了如果Java應(yīng)用是基于GB18030編碼,而數(shù)據(jù)庫編碼是ISO-8859-1的情況,如
47、何通過Java代碼轉(zhuǎn)換字符而不會產(chǎn)生亂碼: 1) 從數(shù)據(jù)庫中讀入含中文的字符串: PreparedStatement pst = ;ResultSet rst = ; String result = rst.getString(1);/從數(shù)據(jù)庫得到某個字段的字符串結(jié)果result = new String(result.getBytes("GB18030");/對result的字符集重新進行編碼,將其強制轉(zhuǎn)為本地GB18030字符集 2) 將中文字符串寫入數(shù)據(jù)庫: PreparedStatement pst = ; sql = new String(sql.getBytes
48、(),"GB18030");/對sql的本地編碼按GB18030進行解碼,還原為數(shù)據(jù)庫能接受的代碼pst.execute(sql); 四、客戶端與服務(wù)器之間的數(shù)據(jù)交換編碼問題從browser到web server,可以在表單中指定提交內(nèi)容時使用的字符集,否則會使用頁面指定的編碼。而如果在url中直接用?的方式輸入?yún)?shù),則其編碼往往是操作系統(tǒng)本身的編碼,因為這時和頁面無關(guān)。Web server接收到的是字節(jié)流,默認(rèn)時(getParameter)會以iso8859-1編碼處理之,結(jié)果是不正確的,所以需要進行處理。但如果預(yù)先設(shè)置了編碼(通過request. setCharacte
49、rEncoding ()),則能夠直接獲取到正確的結(jié)果。4 解決過程(常見問題)下面描述的是我們遇到過得亂碼的解決過程,下面遇到的亂碼所出現(xiàn)問題前6個是在EOS5.X+WebSphere 5.X環(huán)境下發(fā)生的問題,第7個問題是在eos+webLogic下出現(xiàn)的問題4.1 級聯(lián)下拉列表亂碼現(xiàn)象:級聯(lián)下拉選擇列表的內(nèi)容在有的機器上能夠出來,有的機器上出不來,比較了兩臺客戶端機器所安裝的瀏覽器以及操作系統(tǒng)版本以及各自配置完全一樣解決過程:1. 先定位下拉列表的數(shù)據(jù)是否出來:經(jīng)過javascript的跟蹤,發(fā)現(xiàn)下來列表的數(shù)據(jù)已經(jīng)出來了,但是,是亂碼2. 定位亂碼出現(xiàn)的地方(即在什么地方開始數(shù)據(jù)由正常變成
50、亂碼):從級聯(lián)下拉列表的jsp可以知道引用的js文件pageComponentresourcesdynamicSelect.js,而dynamicSelect.js中通過ajax調(diào)用了web.xml上配置的一個名稱叫bizService 的servlet:com.primeton.tp.web.driver.webdriver.PageDriver,知道這個調(diào)用過程后。我們跟蹤到服務(wù)器傳給客戶端就是亂碼,基本確定亂碼產(chǎn)生的原因在服務(wù)器??s小范圍。3. 跟蹤ajax所調(diào)用的servlet的類com.primeton.tp.web.driver.webdriver.PageDriver是在什么地方
51、開始出現(xiàn)亂碼:反編譯類com.primeton.tp.web.driver.webdriver.PageDriver,增加數(shù)據(jù)輸出日志,發(fā)現(xiàn)servlet調(diào)用業(yè)務(wù)邏輯所獲取的數(shù)據(jù)也正常,并沒有出現(xiàn)亂碼。到此,基本定位出字符集由正常變成亂碼是在servlet往瀏覽器輸出的時候出現(xiàn)亂碼。4. 將com.primeton.tp.web.driver.webdriver.PageDriver類反編譯之后,把該類的doPost方法中涉及到設(shè)置字符集的有三處: httpservletrequest.setCharacterEncoding("GBK"); httpservletresp
52、onse.addHeader("Content-Type", "text/xml; charset= GBK "); httpservletresponse.setContentType("text/xml;charset= GBK ");將上面三行代碼中的“GBK”改成“UTF-8”并編譯到服務(wù)器上,并重啟服務(wù)器,問題解決注意:涉及到eos類的修改,不到迫不得已不要修改,如果要修改或者發(fā)現(xiàn)有bug也最好將bug提交bug跟蹤系統(tǒng),讓研發(fā)的同事修改好后再更新。另外,這種亂碼現(xiàn)象并不在其它環(huán)境上發(fā)生,如果發(fā)生我上面所描述的現(xiàn)象,你不妨試
53、試。4.2 隱含提交亂碼隱含提交:即jsp文件中通過引用/fbtools/page/hiddensubmit.js,將客戶端的請求通過ajax提交到fbtoolspagehiddensubmit.jsp現(xiàn)象:在隱含提交的頁面中,輸入中文,保存之后頁面再讀出是亂碼解決過程:修改webSphere的配置文件WAS_HOME/config/cells/smtpserver/applications/eos4ws_wms.ear/deployments/default.war/WEB-INF/ibm-web-ext.xmi,將autoRequestEncoding改成false,重啟服務(wù)器即可注意:如
54、果集群環(huán)境下,必須修改主服務(wù)器即NT的那臺機器,否則,該如果沒有修改主服務(wù)器的配置文件,其它從服務(wù)器的該配置文件將會被主服務(wù)器所覆蓋4.3 EOS控制臺亂碼現(xiàn)象:剛安裝完系統(tǒng),登陸到控制臺,首頁出現(xiàn)帶“?”的亂碼現(xiàn)象解決過程:1、 備份WAS_HOME/lib/webcontainer.jar2、 將WAS_HOME/lib/webcontainer.jar下載到本地,將從林鋒處獲取的claspiler.ParserController替換一下3、 將webcontainer.jar后的jar上傳到WAS_HOME/lib/目錄下覆蓋原來的jar文件注意:如果webSphere升級,將會覆蓋w
55、ebcontainer.jar文件,需要重新把claspiler.ParserController覆蓋一下,另外,大家更新的時候不要去更新其它class,因此要在安裝好webSphere或者升級好的webSphere基礎(chǔ)上獲取WAS_HOME/lib/webcontainer.jar,而不要將別出或者其它版本的webcontainer.jar整個拷貝覆蓋4.4 個別生僻字亂碼(有的漢字亂碼有的漢字不亂碼)現(xiàn)象:界面中出現(xiàn)輸入個別比較生僻的漢字出現(xiàn)亂碼,也不是所有的漢字都出亂碼,有的出,有的不出解決過程:1. cd WAS_HOME/properties目錄2. 打開文件vi ./ encodi
56、perties3. 按esc,輸入:$到該文件的最后行4. 查看打開的文件找到行zh=GB23125. 將zh=GB2312改成zh=GBK,因為常用漢字集合在GBK2312中,收錄漢字6763個。要比生在GBK中共收漢字21004個要少6. 重啟服務(wù)器,問題解決4.5 URL參數(shù)漢字亂碼現(xiàn)象:在WebSphere的基礎(chǔ)上,系統(tǒng)一切運行正常,IBM的工程師升級webSphere2,升級之后出現(xiàn):?參數(shù)1=“帶漢字”,如果參數(shù)值是漢字,則下一個顯示參數(shù)值的頁面出現(xiàn)亂碼解決過程:將WebSphere的版本降下來,由于都是生產(chǎn)環(huán)境,暫時還沒有找到相應(yīng)的環(huán)境來找
57、到問題所在。4.6 從數(shù)據(jù)庫查出來的數(shù)據(jù)亂碼現(xiàn)象:通過db2客戶端工具插入的數(shù)據(jù),程序讀出來是亂碼,而通過程序插入的數(shù)據(jù),程序再讀出來正常, 環(huán)境為AIX上的DB2 8.2,Linux上的WebSphere 5,EOS 5.1.2解決過程:在window客戶端輸入命令:db2set DB2CODEPAGE=,然后將數(shù)據(jù)庫重建,并在建庫的時候就指定字符集UTF-8 (命令如下:create database sccrm using codeset UTF-8 territory CN),然后再初始化數(shù)據(jù),發(fā)現(xiàn)讀出來的數(shù)據(jù)都正常了4.7 EOS+WebLogc9.2存在中文問題現(xiàn)象:
58、將EOS的default應(yīng)用和eosmgr應(yīng)用發(fā)布到WebLogic9.2服務(wù)器上運行時,發(fā)現(xiàn)存在中文問題。解決過程:由于是WebLogic9.2對于通過include 引入的<% page language="java" contentType="text/html; charset=GBK"%>不能正常解析。將eos4wl下面的兩個應(yīng)用default和eosmgr的配置文件weblogic.xml文件中分別加入如下內(nèi)容即可<jsp-descriptor> <jsp-para
59、m> <param-name>compileCommand</param-name> <param-value>javac</param-value> </jsp-param> <jsp-param> <param-name>compilerSupportsEncoding</param-name> <param-value>true</param-value>
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 家俱租賃合同范例
- 2024-2025學(xué)年高中歷史第九單元戊戌變法第1課甲午戰(zhàn)爭后民族危機的加深學(xué)案含解析新人教版選修1
- 工裝 裝修合同范例
- 合作食品合同范例
- 房租漏雨維修合同模板
- 房屋過贈合同范例
- 承包酒店食堂合同范例
- 安裝門窗承包勞務(wù)合同范例
- 會所裝飾服務(wù)合同范例
- 廢舊托盤轉(zhuǎn)讓合同范例
- 催乳穴位及手法課件
- 2023年新改版教科版六年級下冊科學(xué)全冊知識點 (共兩套)
- 隧道圍巖分級(表)
- 國家開放大學(xué)《液壓與氣壓傳動》形考任務(wù)1-2參考答案
- 食道超聲在心臟外科手術(shù)中的應(yīng)用課件
- 9《 復(fù)活》課件17張PPT 統(tǒng)編版高中語文選擇性必修上冊第三單元
- 血流動力學(xué)不穩(wěn)定骨盆骨折急診處理
- 新《刑法-刑罰》考試題庫大全(含詳解)
- 小學(xué)醫(yī)學(xué)知識(課堂)課件
- 客戶個人信息保護突發(fā)事件應(yīng)急預(yù)案
- 三年級下冊科學(xué)活動手冊
評論
0/150
提交評論