① java中利用JDBC向Mysql資料庫中插入中文出現亂碼,求解決辦法
你應該是安裝mysql的時候編碼你是選擇默認的吧。
你可以找到mysql的安裝目錄MySQL Server 5.0\bin\MySQLInstanceConfig.exe
重新配置下就可以了。一般選擇utf-8編碼。
再一個如果資料庫開始就建立好了。alter database 表名 character set utf8;
連接資料庫設置編碼
jdbc:mysql://地址:3306/資料庫名?characterEncoding=utf8
如果是windows的話
1、中止MySQL服務
2、在MySQL的安裝目錄下找到my.ini,如果沒有就把my-medium.ini復制為一個my.ini即可
3、打開my.ini以後,在[client]和[mysqld]下面均加上default-character-set=utf8,保存並關閉
4、啟動MySQL服務
② 為什麼mysql可以顯示中文,但用Java讀出的中文卻是亂碼
資料庫引擎和開發語言所應用的文字編碼不一致,就會導致出現亂碼!
將你所編寫的JavaSource用文字編碼Class來重新設定一下就可以了。
String 變數名 = new String(變數名.getBytes("ISO-8859-1"),"資料庫的文字編碼");
利用什麼編碼無所謂,關鍵是雙方一致才可以。
推薦用 utf-8
剩下的就看你自己了。
③ JAVA中向mysql資料庫中添加信息,資料庫中顯示亂碼怎麼解決,資料庫是utf-8具體要怎麼做才能解決
基礎知識
計算機中儲存的信息都是用二進制數表示的;而我們在屏幕上看到的英文、漢字等字元是二進制數轉換之後的結果。通俗的說,按照何種規則將字元存儲在計算機中,如'a'用什麼表示,稱為"編碼";反之,將存儲在計算機中的二進制數解析顯示出來,稱為"解碼",如同密碼學中的加密和解密。在解碼過程中,如果使用了錯誤的解碼規則,則導致'a'解析成'b'或者亂碼。
字元集(Charset):是一個系統支持的所有抽象字元的集合。字元是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。
字元編碼(Character Encoding):是一套法則,使用該法則能夠對自然語言的字元的一個集合(如字母表或音節表),與其他東西的一個集合(如號碼或電脈沖)進行配對。即在符號集合與數字系統之間建立對應關系,它是信息處理的一項基本技術。通常人們用符號集合(一般情況下就是文字)來表達信息。而以計算機為基礎的信息處理系統則是利用元件(硬體)不同狀態的組合來存儲和處理信息的。元件不同狀態的組合能代表數字系統的數字,因此字元編碼就是將符號轉換為計算機可以接受的數字系統的數,稱為數字代碼。
2.常用字元集和字元編碼
常見字元集名稱:ASCII字元集、GB2312字元集、BIG5字元集、GB18030字元集、Unicode字元集等。計算機要准確的處理各種字元集文字,需要進行字元編碼,以便計算機能夠識別和存儲各種文字。
2.1. ASCII字元集&編碼
ASCII(AmericanStandardCode forInformationInterchange,美國信息交換標准代碼)是基於拉丁字母的一套電腦編碼系統。它主要用於顯示現代英語,而其擴展版本EASCII則可以勉強顯示其他西歐語言。它是現今最通用的單位元組編碼系統(但是有被Unicode追上的跡象),並等同於國際標准ISO/IEC 646。
ASCII字元集:主要包括控制字元(回車鍵、退格、換行鍵等);可顯示字元(英文大小寫字元、阿拉伯數字和西文符號)。
ASCII編碼:將ASCII字元集轉換為計算機可以接受的數字系統的數的規則。使用7位(bits)表示一個字元,共128字元;但是7位編碼的字元集只能支持128個字元,為了表示更多的歐洲常用字元對ASCII進行了擴展,ASCII擴展字元集使用8位(bits)表示一個字元,共256字元。ASCII字元集映射到數字編碼規則如下圖所示:
圖1 ASCII編碼表
圖2 擴展ASCII編碼表
ASCII的最大缺點是只能顯示26個基本拉丁字母、阿拉伯數目字和英式標點符號,因此只能用於顯示現代美國英語(而且在處理英語當中的外來詞如naïve、café、élite等等時,所有重音符號都不得不去掉,即使這樣做會違反拼寫規則)。而EASCII雖然解決了部份西歐語言的顯示問題,但對更多其他語言依然無能為力。因此現在的蘋果電腦已經拋棄ASCII而轉用Unicode。
2.2. GBXXXX字元集&編碼
計算機發明之處及後面很長一段時間,只用應用於美國及西方一些發達國家,ASCII能夠很好滿足用戶的需求。但是當天朝也有了計算機之後,為了顯示中文,必須設計一套編碼規則用於將漢字轉換為計算機可以接受的數字系統的數。
天朝專家把那些127號之後的奇異符號們(即EASCII)取消掉,規定:一個小於127的字元的意義與原來相同,但兩個大於127的字元連在一起時,就表示一個漢字,前面的一個位元組(他稱之為高位元組)從0xA1用到 0xF7,後面一個位元組(低位元組)從0xA1到0xFE,這樣我們就可以組合出大約7000多個簡體漢字了。在這些編碼里,還把數學符號、羅馬希臘的 字母、日文的假名們都編進去了,連在ASCII里本來就有的數字、標點、字母都統統重新編了兩個位元組長的編碼,這就是常說的"全形"字元,而原來在127號以下的那些就叫"半形"字元了。
上述編碼規則就是GB2312。GB2312或GB2312-80是中國國家標准簡體中文字元集,全稱《信息交換用漢字編碼字元集·基本集》,又稱GB0,由中國國家標准總局發布,1981年5月1日實施。GB2312編碼通行於中國大陸;新加坡等地也採用此編碼。中國大陸幾乎所有的中文系統和國際化的軟體都支持GB2312。GB2312的出現,基本滿足了漢字的計算機處理需要,它所收錄的漢字已經覆蓋中國大陸99.75%的使用頻率。對於人名、古漢語等方面出現的罕用字,GB2312不能處理,這導致了後來GBK及GB 18030漢字字元集的出現。下圖是GB2312編碼的開始部分(由於其非常龐大,只列舉開始部分,具體可查看GB2312簡體中文編碼表):
圖3 GB2312編碼表的開始部分
由於GB 2312-80隻收錄6763個漢字,有不少漢字,如部分在GB 2312-80推出以後才簡化的漢字(如"啰"),部分人名用字(如中國前總理朱鎔基的"鎔"字),台灣及香港使用的繁體字,日語及朝鮮語漢字等,並未有收錄在內。於是廠商微軟利用GB 2312-80未使用的編碼空間,收錄GB 13000.1-93全部字元制定了GBK編碼。根據微軟資料,GBK是對GB2312-80的擴展,也就是CP936字碼表 (Code Page 936)的擴展(之前CP936和GB 2312-80一模一樣),最早實現於Windows 95簡體中文版。雖然GBK收錄GB 13000.1-93的全部字元,但編碼方式並不相同。GBK自身並非國家標准,只是曾由國家技術監督局標准化司、電子工業部科技與質量監督司公布為"技術規范指導性文件"。原始GB13000一直未被業界採用,後續國家標准GB18030技術上兼容GBK而非GB13000。
GB 18030,全稱:國家標准GB 18030-2005《信息技術 中文編碼字元集》,是中華人民共和國現時最新的內碼字集,是GB 18030-2000《信息技術 信息交換用漢字編碼字元集 基本集的擴充》的修訂版。與GB2312-1980完全兼容,與GBK基本兼容,支持GB13000及Unicode的全部統一漢字,共收錄漢字70244個。GB 18030主要有以下特點:
與UTF-8相同,採用多位元組編碼,每個字可以由1個、2個或4個位元組組成。
編碼空間龐大,最多可定義161萬個字元。
支持中國國內少數民族的文字,不需要動用造字區。
漢字收錄范圍包含繁體漢字以及日韓漢字
圖4 GB18030編碼總體結構
本規格的初版使中華人民共和國信息產業部電子工業標准化研究所起草,由國家質量技術監督局於2000年3月17日發布。現行版本為國家質量監督檢驗總局和中國國家標准化管理委員會於2005年11月8日發布,2006年5月1日實施。此規格為在中國境內所有軟體產品支持的強制規格。
2.3. BIG5字元集&編碼
Big5,又稱為大五碼或五大碼,是使用繁體中文(正體中文)社區中最常用的電腦漢字字元集標准,共收錄13,060個漢字。中文碼分為內碼及交換碼兩類,Big5屬中文內碼,知名的中文交換碼有CCCII、CNS11643。Big5雖普及於台灣、香港與澳門等繁體中文通行區,但長期以來並非當地的國家標准,而只是業界標准。倚天中文系統、Windows等主要系統的字元集都是以Big5為基準,但廠商又各自增加不同的造字與造字區,派生成多種不同版本。2003年,Big5被收錄到CNS11643中文標准交換碼的附錄當中,取得了較正式的地位。這個最新版本被稱為Big5-2003。
Big5碼是一套雙位元組字元集,使用了雙八碼存儲方法,以兩個位元組來安放一個字。第一個位元組稱為"高位位元組",第二個位元組稱為"低位位元組"。"高位位元組"使用了0x81-0xFE,"低位位元組"使用了0x40-0x7E,及0xA1-0xFE。在Big5的分區中:
0x8140-0xA0FE
保留給用戶自定義字元(造字區)
0xA140-0xA3BF
標點符號、希臘字母及特殊符號,包括在0xA259-0xA261,安放了九個計量用漢字:兙兛兞兝兡兣嗧瓩糎。
0xA3C0-0xA3FE
保留。此區沒有開放作造字區用。
0xA440-0xC67E
常用漢字,先按筆劃再按部首排序。
0xC6A1-0xC8FE
保留給用戶自定義字元(造字區)
0xC940-0xF9D5
次常用漢字,亦是先按筆劃再按部首排序。
0xF9D6-0xFEFE
保留給用戶自定義字元(造字區)
Unicode字元集&UTF編碼
3.偉大的創想Unicode
——不得不單獨說Unicode
像天朝一樣,當計算機傳到世界各個國家時,為了適合當地語言和字元,設計和實現類似GB232/GBK/GB18030/BIG5的編碼方案。這樣各搞一套,在本地使用沒有問題,一旦出現在網路中,由於不兼容,互相訪問就出現了亂碼現象。
為了解決這個問題,一個偉大的創想產生了——Unicode。Unicode編碼系統為表達任意語言的任意字元而設計。它使用4位元組的數字來表達每個字母、符號,或者表意文字(ideograph)。每個數字代表唯一的至少在某種語言中使用的符號。(並不是所有的數字都用上了,但是總數已經超過了65535,所以2個位元組的數字是不夠用的。)被幾種語言共用的字元通常使用相同的數字來編碼,除非存在一個在理的語源學(etymological)理由使不這樣做。不考慮這種情況的話,每個字元對應一個數字,每個數字對應一個字元。即不存在二義性。不再需要記錄"模式"了。U+0041總是代表'A',即使這種語言沒有'A'這個字元。
在計算機科學領域中,Unicode(統一碼、萬國碼、單一碼、標准萬國碼)是業界的一種標准,它可以使電腦得以體現世界上數十種文字的系統。Unicode 是基於通用字元集(Universal Character Set)的標准來發展,並且同時也以書本的形式[1]對外發表。Unicode 還不斷在擴增, 每個新版本插入更多新的字元。直至目前為止的第六版,Unicode 就已經包含了超過十萬個字元(在2005年,Unicode 的第十萬個字元被採納且認可成為標准之一)、一組可用以作為視覺參考的代碼圖表、一套編碼方法與一組標准字元編碼、一套包含了上標字、下標字等字元特性的枚舉等。Unicode 組織(The Unicode Consortium)是由一個非營利性的機構所運作,並主導 Unicode 的後續發展,其目標在於:將既有的字元編碼方案以Unicode 編碼方案來加以取代,特別是既有的方案在多語環境下,皆僅有有限的空間以及不兼容的問題。
(可以這樣理解:Unicode是字元集,UTF-32/ UTF-16/ UTF-8是三種字元編碼方案。)
3.1.UCS & UNICODE
通用字元集(Universal Character Set,UCS)是由ISO制定的ISO 10646(或稱ISO/IEC 10646)標准所定義的標准字元集。歷史上存在兩個獨立的嘗試創立單一字元集的組織,即國際標准化組織(ISO)和多語言軟體製造商組成的統一碼聯盟。前者開發的 ISO/IEC 10646 項目,後者開發的統一碼項目。因此最初制定了不同的標准。
1991年前後,兩個項目的參與者都認識到,世界不需要兩個不兼容的字元集。於是,它們開始合並雙方的工作成果,並為創立一個單一編碼表而協同工作。從Unicode 2.0開始,Unicode採用了與ISO 10646-1相同的字型檔和字碼;ISO也承諾,ISO 10646將不會替超出U+10FFFF的UCS-4編碼賦值,以使得兩者保持一致。兩個項目仍都存在,並獨立地公布各自的標准。但統一碼聯盟和ISO/IEC JTC1/SC2都同意保持兩者標準的碼表兼容,並緊密地共同調整任何未來的擴展。在發布的時候,Unicode一般都會採用有關字碼最常見的字型,但ISO 10646一般都盡可能採用Century字型。
3.2.UTF-32
上述使用4位元組的數字來表達每個字母、符號,或者表意文字(ideograph),每個數字代表唯一的至少在某種語言中使用的符號的編碼方案,稱為UTF-32。UTF-32又稱UCS-4是一種將Unicode字元編碼的協定,對每個字元都使用4位元組。就空間而言,是非常沒有效率的。
這種方法有其優點,最重要的一點就是可以在常數時間內定位字元串里的第N個字元,因為第N個字元從第4×Nth個位元組開始。雖然每一個碼位使用固定長定的位元組看似方便,它並不如其它Unicode編碼使用得廣泛。
3.3.UTF-16
盡管有Unicode字元非常多,但是實際上大多數人不會用到超過前65535個以外的字元。因此,就有了另外一種Unicode編碼方式,叫做UTF-16(因為16位 = 2位元組)。UTF-16將0–65535范圍內的字元編碼成2個位元組,如果真的需要表達那些很少使用的"星芒層(astral plane)"內超過這65535范圍的Unicode字元,則需要使用一些詭異的技巧來實現。UTF-16編碼最明顯的優點是它在空間效率上比UTF-32高兩倍,因為每個字元只需要2個位元組來存儲(除去65535范圍以外的),而不是UTF-32中的4個位元組。並且,如果我們假設某個字元串不包含任何星芒層中的字元,那麼我們依然可以在常數時間內找到其中的第N個字元,直到它不成立為止這總是一個不錯的推斷。其編碼方法是:
如果字元編碼U小於0x10000,也就是十進制的0到65535之內,則直接使用兩位元組表示;
如果字元編碼U大於0x10000,由於UNICODE編碼范圍最大為0x10FFFF,從0x10000到0x10FFFF之間 共有0xFFFFF個編碼,也就是需要20個bit就可以標示這些編碼。用U'表示從0-0xFFFFF之間的值,將其前 10 bit作為高位和16 bit的數值0xD800進行 邏輯or 操作,將後10 bit作為低位和0xDC00做 邏輯or 操作,這樣組成的 4個byte就構成了U的編碼。
對於UTF-32和UTF-16編碼方式還有一些其他不明顯的缺點。不同的計算機系統會以不同的順序保存位元組。這意味著字元U+4E2D在UTF-16編碼方式下可能被保存為4E 2D或者2D 4E,這取決於該系統使用的是大尾端(big-endian)還是小尾端(little-endian)。(對於UTF-32編碼方式,則有更多種可能的位元組排列。)只要文檔沒有離開你的計算機,它還是安全的——同一台電腦上的不同程序使用相同的位元組順序(byte order)。但是當我們需要在系統之間傳輸這個文檔的時候,也許在萬維網中,我們就需要一種方法來指示當前我們的位元組是怎樣存儲的。不然的話,接收文檔的計算機就無法知道這兩個位元組4E 2D表達的到底是U+4E2D還是U+2D4E。
為了解決這個問題,多位元組的Unicode編碼方式定義了一個"位元組順序標記(Byte Order Mark)",它是一個特殊的非列印字元,你可以把它包含在文檔的開頭來指示你所使用的位元組順序。對於UTF-16,位元組順序標記是U+FEFF。如果收到一個以位元組FF FE開頭的UTF-16編碼的文檔,你就能確定它的位元組順序是單向的(one way)的了;如果它以FE FF開頭,則可以確定位元組順序反向了。
3.4.UTF-8
UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字元編碼(定長碼),也是一種前綴碼。它可以用來表示Unicode標准中的任何字元,且其編碼中的第一個位元組仍與ASCII兼容,這使得原來處理ASCII字元的軟體無須或只須做少部份修改,即可繼續使用。因此,它逐漸成為電子郵件、網頁及其他存儲或傳送文字的應用中,優先採用的編碼。互聯網工程工作小組(IETF)要求所有互聯網協議都必須支持UTF-8編碼。
UTF-8使用一至四個位元組為每個字元編碼:
128個US-ASCII字元只需一個位元組編碼(Unicode范圍由U+0000至U+007F)。
帶有附加符號的拉丁文、希臘文、西里爾字母、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文及它拿字母則需要二個位元組編碼(Unicode范圍由U+0080至U+07FF)。
其他基本多文種平面(BMP)中的字元(這包含了大部分常用字)使用三個位元組編碼。
其他極少使用的Unicode輔助平面的字元使用四位元組編碼。
在處理經常會用到的ASCII字元方面非常有效。在處理擴展的拉丁字元集方面也不比UTF-16差。對於中文字元來說,比UTF-32要好。同時,(在這一條上你得相信我,因為我不打算給你展示它的數學原理。)由位操作的天性使然,使用UTF-8不再存在位元組順序的問題了。一份以utf-8編碼的文檔在不同的計算機之間是一樣的比特流。
總體來說,在Unicode字元串中不可能由碼點數量決定顯示它所需要的長度,或者顯示字元串之後在文本緩沖區中游標應該放置的位置;組合字元、變寬字體、不可列印字元和從右至左的文字都是其歸因。所以盡管在UTF-8字元串中字元數量與碼點數量的關系比UTF-32更為復雜,在實際中很少會遇到有不同的情形。
優點
UTF-8是ASCII的一個超集。因為一個純ASCII字元串也是一個合法的UTF-8字元串,所以現存的ASCII文本不需要轉換。為傳統的擴展ASCII字元集設計的軟體通常可以不經修改或很少修改就能與UTF-8一起使用。
使用標準的面向位元組的排序常式對UTF-8排序將產生與基於Unicode代碼點排序相同的結果。(盡管這只有有限的有用性,因為在任何特定語言或文化下都不太可能有仍可接受的文字排列順序。)
UTF-8和UTF-16都是可擴展標記語言文檔的標准編碼。所有其它編碼都必須通過顯式或文本聲明來指定。
任何面向位元組的字元串搜索演算法都可以用於UTF-8的數據(只要輸入僅由完整的UTF-8字元組成)。但是,對於包含字元記數的正則表達式或其它結構必須小心。
UTF-8字元串可以由一個簡單的演算法可靠地識別出來。就是,一個字元串在任何其它編碼中表現為合法的UTF-8的可能性很低,並隨字元串長度增長而減小。舉例說,字元值C0,C1,F5至FF從來沒有出現。為了更好的可靠性,可以使用正則表達式來統計非法過長和替代值(可以查看W3 FAQ: Multilingual Forms上的驗證UTF-8字元串的正則表達式)。
缺點
因為每個字元使用不同數量的位元組編碼,所以尋找串中第N個字元是一個O(N)復雜度的操作 — 即,串越長,則需要更多的時間來定位特定的字元。同時,還需要位變換來把字元編碼成位元組,把位元組解碼成字元。
4.Accept-Charset/Accept-Encoding/Accept-Language/Content-Type/Content-Encoding/Content-Language
在HTTP中,與字元集和字元編碼相關的消息頭是Accept-Charset/Content-Type,另外主區區分Accept-Charset/Accept-Encoding/Accept-Language/Content-Type/Content-Encoding/Content-Language:
Accept-Charset:瀏覽器申明自己接收的字元集,這就是本文前面介紹的各種字元集和字元編碼,如gb2312,utf-8(通常我們說Charset包括了相應的字元編碼方案);
Accept-Encoding:瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什麼壓縮方法(gzip,deflate),(注意:這不是隻字元編碼);
Accept-Language:瀏覽器申明自己接收的語言。語言跟字元集的區別:中文是語言,中文有多種字元集,比如big5,gb2312,gbk等等;
Content-Type:WEB伺服器告訴瀏覽器自己響應的對象的類型和字元集。例如:Content-Type: text/html; charset='gb2312'
Content-Encoding:WEB伺服器表明自己使用了什麼壓縮方法(gzip,deflate)壓縮響應中的對象。例如:Content-Encoding:gzip
Content-Language:WEB伺服器告訴瀏覽器自己響應的對象的語言。
資源來源於:http://blog.chinaunix.net/uid-22145625-id-3294658.html
④ java mysql資料庫 Blob亂碼 求救。
應該是
字元集
的問題。
最好都設成utf-8
包括資料庫,後台,還有前台頁面的編碼
⑤ java後台向mysql插入數據,資料庫中顯示亂碼
MySQL中默認字元集的設置有四級:伺服器級,資料庫級,表級
。最終是欄位級
的字元集設置。注意前三種均為默認設置,並不代碼你的欄位最終會使用這個字元集設置。所以我們建議要用show
create
table
table
;
或show
full
fields
from
tableName;
來檢查當前表中欄位的字元集設置。
MySQL中關於連接環境的字元集設置有
Client端,connection,
results
通過這些參數,MySQL就知道你的客戶端工具用的是什麼字元集,結果集應該是什麼字元集。這樣MySQL就會做必要的翻譯,一旦這些參數有誤,自然會導致字元串在轉輸過程中的轉換錯誤。基本上99%的亂碼由些造成。
上面是我抄網上的資料來的。我試了一下。發現
mysql>
show
variables
like
'char%';
+--------------------------+----------------------------+
|
Variable_name
|
Value
|
+--------------------------+----------------------------+
|
character_set_client
|
latin1
|
|
character_set_connection
|
latin1
|
|
character_set_database
|
latin1
|
|
character_set_filesystem
|
binary
|
|
character_set_results
|
latin1
|
|
character_set_server
|
latin1
|
|
character_set_system
|
utf8
|
|
character_sets_dir
|
/usr/share/mysql/charsets/
|
+--------------------------+----------------------------+
8
rows
in
set
(0.00
sec)
解決方法已經找到。進入數據後
use
資料庫名;
names
utf8;
不過這樣會每次進入都必須重新設置。因此。還可以在/etc/mysql/my.conf里添加
[mysql]
#no-auto-rehash
#
faster
start
of
mysql
but
no
tab
completition
default-character-set=utf8
這樣資料庫就不每次按照utf8字元集來導入到資料庫了
⑥ 在navicat創建資料庫和表,然後填入記錄,為什麼用java連接mysql的時候,顯示出來的結果中,漢字是問號
因為編碼格式不一致導致的
mysql默認編碼為latin1,而你的頁面採用的編碼格式很可能是GBK或ISO-8859-1或者utf-8,你可以用navaicat設置表的編碼格式與你頁面的編碼格式一致,都設置成utf-8,就不會出現?的亂碼了,還有最好在java連接mysql的連接串中指明使用的編碼格式,例如:localhost:3306/mydatabase??useUnicode=true;characterEncoding=UTF-8
⑦ 通過JAVA向MYSQL中添加數據時,數據有漢子,在MYSQL中顯示亂碼(問號)
中文亂碼問題通常有以下幾個方面造成:
1)資料庫的編碼問題。建立資料庫的時候確保字元編碼是GBK或UTF-8,這樣才能支持中文。
2)頁面的編碼問題。確保Java程序裡面或者HTML/JSP頁面的編碼也是GBK或者UTF-8。
<%@pagelanguage="java"contentType="text/html;charset=GBK"
pageEncoding="GBK"%>
3)Java後台程序的編碼問題。如果是Web項目,可以使用以下代碼進行字元編碼設置,保證編碼為GBK或UTF-8。
request.setCharacterEncoding("GBK");
⑧ mysql 資料庫後台 亂碼問題 全市問號 怎麼辦
最後用到的一句代碼是:
<%= new String(rst.getString(2).getBytes("ISO-8859-1"),"gb2312")%>
大家在JSP的開發過程中,經常出現中文亂碼的問題,可能一至困擾著您,我現在把我在JSP開發中遇到的中文亂碼的問題及解決辦法寫出來供大家參考。
一、JSP頁面顯示亂碼
下面的顯示頁面(display.jsp)就出現亂碼:
對不同的WEB伺服器和不同的JDK版本,處理結果就不一樣。原因:伺服器使用的編碼方式不同和瀏覽器對不同的字元顯示結果不同而導致的。解決辦法:在JSP頁面中指定編碼方式(gb2312),即在頁面的第一行加上:,就可以消除亂碼了。完整頁面如下:
二、表單提交中文時出現亂碼
下面是一個提交頁面(submit.jsp),代碼如下:
下面是處理頁面(process.jsp)代碼:
如果submit.jsp提交英文字元能正確顯示,如果提交中文時就會出現亂碼。原因:瀏覽器默認使用UTF-8編碼方式來發送請求,而UTF-8和GB2312編碼方式表示字元時不一樣,這樣就出現了不能識別字元。解決辦法:通過request.seCharacterEncoding("gb2312")對請求進行統一編碼,就實現了中文的正常顯示。修改後的process.jsp代碼如下:
三、資料庫連接出現亂碼
只要涉及中文的地方全部是亂碼,解決辦法:在資料庫的資料庫URL中加上useUnicode=true&characterEncoding=GBK就OK了。
四、資料庫的顯示亂碼
在mysql4.1.0中,varchar類型,text類型就會出現中文亂碼,對於varchar類型把它設為binary屬性就可以解決中文問題,對於text類型就要用一個編碼轉換類來處理,實現如下:
public class Convert {
/** 把ISO-8859-1碼轉換成GB2312
*/
public static String ISOtoGB(String iso){
String gb;
try{
if(iso.equals("") || iso == null){
return "";
}
else{
iso = iso.trim();
gb = new String(iso.getBytes("ISO-8859-1"),"GB2312");
return gb;
}
}
catch(Exception e){
System.err.print("編碼轉換錯誤:"+e.getMessage());
return "";
}
}
}
把它編譯成class,就可以調用Convert類的靜態方法ISOtoGB()來轉換編碼。
和Java一樣,JSP是目前比較熱門的一個話題。它是一種在伺服器端編譯執行的Web設計語言,因為腳本語言採用了Java,所以JSP繼承了Java的所有優點。可是在使用JSP程序的過程中,常遇到中文亂碼問題,很多人為此頭疼不已,筆者就深受其害,而且使用平台不同,中文亂碼問題的解決方法也不同,無形中增加了學習JSP的難度。其實,在徹底了解相關原因後,問題還是比較容易解決的。筆者結合自己的工作實踐,對中文顯示問題進行了一定的研究,並在不同的環境下進行了相關測試,以下是筆者總結的解決方法,相信對讀者會有一定的借鑒意義。
字元內碼
每個國家(或區域)都規定了計算機信息交換用的字元編碼集,如美國的擴展ASCII碼、中國的GB2312-80、日本的 JIS 等,作為該國家(區域)信息處理的基礎,有著統一編碼的重要作用。由於各本地字元集代碼范圍重疊,相互間信息交換困難,軟體本地化版本獨立維護成本較高。因此有必要將本地化工作中的共性抽取出來,做一致性處理,將特殊的本地化處理內容降低到最少,這就是所謂的國際化(I18N)。各種語言信息被規范為本地信息,而底層字元集採用包含了所有字元的Unicode。
字元內碼(character code)指的是用來代表字元的內碼。我們在輸入和存儲文檔時都要使用內碼,內碼分為單位元組內碼和雙位元組內碼。單位元組內碼的英文全稱是Single-Byte Character Sets (SBCS),可以支持256個字元編碼;雙位元組內碼的英文全稱是Double-Byte Character Sets(DBCS),可以支持65000個字元編碼,主要用來對大字元集的東方文字進行編碼。
CodePage指的是一個經過挑選的以特定順序排列的字元內碼列表,對於早期的單位元組內碼的語種,CodePage中的內碼順序使得系統可以按照此列表來根據鍵盤的輸入值給出一個對應的內碼。對於雙位元組內碼,給出的是MultiByte到Unicode的對應表,這樣就可以把以Unicode形式存放的字元轉化為相應的字元內碼。引入對CodePage的支持主要是為了訪問多語種文件名,目前在NTFS和FAT32/VFAT下的文件系統上都使用Unicode,這需要系統在讀取這些文件名時動態地將其轉換為相應的語言編碼。
相信了解JSP代碼的讀者對ISO8859-1一定不陌生,ISO8859-1是我們平時使用比較多的一個CodePage,它屬於西歐語系。GB2312-80 是在國內計算機漢字信息技術發展初始階段制訂的,其中包含了大部分常用的一、二級漢字和9區的符號。該字元集是幾乎所有的中文系統和國際化的軟體都支持的中文字元集,這也是最基本的中文字元集。
GBK 是 GB2312-80 的擴展,是向上兼容的。它包含了20902個漢字,其編碼范圍是 0x8140~0xFEFE,剔除高位 0x80 的字位,其所有字元都可以一對一映射到 Unicode 2.0,也就是說 Java 實際上提供了對 GBK 字元集的支持。
>GB18030-2000(GBK2K) 在 GBK 的基礎上進一步擴展了漢字,增加了藏、蒙等少數民族的文字。GBK2K 從根本上解決了字位不夠、字形不足的問題。
不同開發平台的區別
1.Tomcat 4開發平台
Windows 98/2000下的Tomcat 4以上版本都會出現中文問題(而在Linux下和Tomcat 3.x中則沒有問題),主要表現是頁面顯示亂碼。在IE中調整字元集為GB2312,就可以正常顯示了。
為解決這個問題,可在每個JSP的頁面開始處加上。不過,這還不夠,雖然這時顯示了中文,但是發現從資料庫讀出的欄位變成了亂碼。經過分析發現: 在資料庫中保存的中文字元是正常的,資料庫用ISO8859-1字元集存取數據,而Java程序在處理字元時默認採用統一的ISO8859-1字元集(這也體現了Java國際化思想),所以在數據添加的時候Java和資料庫都是以ISO8859-1方式處理,這樣不會出錯。但是在讀取數據的時候就出現問題了,因為數據讀出也採用ISO8859-1字元集,而 JSP的文件頭中有語句,這說明頁面採用GB2312的字元集顯示,這樣就和讀出的數據不一樣。這時頁面顯示從資料庫中讀出的字元是亂碼,解決的方法是對這些字元轉碼,從ISO8859-1轉成GB2312,就可以正常顯示了。這個解決辦法對很多平台具有通用性,讀者可以靈活運用。
2.Tomcat 3.x、Resin及Linux平台
在Tomcat 3.x、Resin中或是在Linux下,沒有加入語句,而頁面中的語句起了作用,此時可以正常顯示。相反,如果加上系統會報錯,說明Tomcat 4以上版本的引擎在處理JSP時還是有差別的。
另外,對於不同的資料庫如SQL Server,Oracle,Mysql,Sybase等,字元集的選擇很重要。如果考慮多語言版本,資料庫的字元集就應該統一採用ISO8859-1,需要輸出的時候在不同的字元集之間做轉換就可以了。
以下是針對不同平台的總結:
(1) JSWDK只適合於普通開發,穩定性和其他問題可能不如商業軟體。 由於JDK 1.3版性能要好於JDK 1.2.2很多,並且對中文的支持也較好,所以應該盡量採用。
(2) 作為免費的商業軟體,Resin不僅速度快、穩定、自動編譯,還可以指出出錯行,並可在伺服器端支持使用JavaScript等,而且對中文的支持也很好。
(3) Tomcat僅僅是一個對JSP 1.1、Servlet 2.2標準的實現, 我們不應該要求這個免費軟體在細節和性能上都面面俱到, 它主要考慮英文用戶, 這也是為什麼不做特殊轉換,漢字用URL方法傳遞就有問題的原因。大部分IE瀏覽器預設始終以UTF-8發送, 這似乎是Tomcat的一個不足, 另外Tomcat不管當前的操作系統是什麼語言, 都按ISO8859去編譯JSP, 似乎也欠妥。
JSP代碼的中文處理
在JSP代碼中以下幾處經常需要涉及到中文處理:
1. 在URL中附帶中文參數。這里中文參數通常可以直接讀取,例如:
2. 在JSWDK中讀取HTML表單提交的中文值這時需要加以編碼,較為簡潔的寫法是:
String name1=new String(request.getParameter(「user_id」).getBytes(「ISO8859_1」))。
另外,在JDK 1.3的支持下,不需加入 ,而在JDK 1.2.2 以下,即使以上兩種方法同時運用也很不穩定。但在Resin平台,情況較好,只要在頁面第一行加入:即可正確處理中文,如果再加代碼則反而不對。
3.在JSWDK中Session包含的中文,如果從表單中讀出的值經過編碼可正確顯示,但直接賦予中文值則不行,而Resin平台則很好。
4. 在編譯Servlet和JSP時加入代碼選項。在編譯Servlet時使用Java-Encoding ISO8859-1 myservlet.java;在JSP的ZONE配置文件中,修改編譯參數為:Compiler=builtin - javac- encoding ISO8859-1。使用這種方法後,不需要做其他的改動就可以正常顯示中文了。
另外,流行的關系資料庫系統都支持資料庫Encoding,也就是說在創建資料庫時可以指定它自己的字元集設置,資料庫的數據以指定的編碼形式存儲。當應用程序訪問數據時,在入口和出口處都會有 Encoding 轉換。對於中文數據,資料庫字元編碼的設置應當保證數據的完整性。 GB2312、GBK、UTF-8 等都是可選的資料庫 Encoding,也可以選擇 ISO8859-1 (8-bit), 但會增加了編程的復雜度,ISO8859-1不是推薦的資料庫 Encoding。在JSP/Servlet編程時,可以先用資料庫管理系統提供的管理功能檢查其中的中文數據是否正確。
處理方法實例
下面是兩個具體的中文亂碼解決實例,讀者仔細研究後可能會有所收獲。
1.常見的字元轉換方法
將Form 中 的 值 傳 送 到 數 據 庫 中 再 取 出 來 後 全 變 成 了「?」。Form用POST提交數據,代碼中使用了語句:String st=new(request.getParameter(「name」).getBytes(「ISO8859_1」)), 而且也聲明了charset=gb2312。
要處理Form中傳遞的中文參數,應該在JSP中加入下面的代碼,另外定義一個專門解決這個問題的getStr類,然後對接收到的參數進行轉換:
String keyword1=request.getParameter(「keyword1」);
keyword1=getStr(keyword1);
這樣就可以解決問題了,代碼如下:
2. JDBC Driver的字元轉換
目前大多數JDBC Driver採用本地編碼格式來傳輸中文字元,例如中文字元「0x4175」會被轉成「0x41」和「0x75」進行傳輸。因此需要對JDBC Driver返回的字元以及要發給JDBC Driver的字元進行轉換。當用JDBC Driver向資料庫中插入數據時,需要先將Unicode轉成Native code; 當 JDBC Driver從資料庫中查詢數據時,則需要將Native code轉換成Unicode。下面給出了這兩種轉換的實現:
String native2Unicode(String s) {
if (s == null || s.length() == 0) {
return null;
}
byte[] buffer = new byte[s.length()];
for (int i = 0; i s.length(); i++) { if (s.charAt(i)>= 0x100) {
c = s.charAt(i);
byte []buf = (「」+c).getBytes();
buffer[j++] = (char)buf[0];
buffer[j++] = (char)buf[1];
}
else {buffer[j++] = s.charAt(i);}
}
return new String(buffer, 0, j);
}
要注意的是,有些JDBC Driver如果通過JDBC Driver Manager設置了正確的字元集屬性,以上方法就不需要了。具體情況可參考相關JDBC的資料。
⑨ 各位大俠,本人利用javaweb讀取mysql資料庫中的數據,但是中文字體顯示的是問號,請問這種情況如何處理
你是顯示到頁面上還是在控制台上啊?可是設置編碼的。response.setCharcacterEncoding("UTF-8"),試試看。希望能幫到你。