java字符編碼和oracle亂碼


編碼問題我仍舊沒搞懂,最根本的從哪里來就沒搞懂。當頁面發送請求,編碼到后台是什么編碼呢?好吧,我默認的都是utf-8.后台接收參數后,可以在控制台打印出來,我也不清楚是什么編碼。然后,就是數據庫問題。

在mysql數據庫,首先會設置mysql安裝的字符集為utf-8,然后在連接的jdbc上注明characterEncoding是utf-8.一直這樣統一下去,沒有出現亂碼。

連接oracle就出現問題了,我使用的一個已經安裝好的oracle數據庫。字符集是American,us7ascii.我插入和查詢的中文都是亂碼。百度了很久之后,還是進行轉碼工作。

關於java編碼,先看String中的幾個方法:

getBytes()

1 byte[] java.lang.String.getBytes(String charsetName) throws UnsupportedEncodingException
2 
3 
4 Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array. 
5 
6 The behavior of this method when this string cannot be encoded in the given charset is unspecified. The java.nio.charset.CharsetEncoder class should be used when more control over the encoding process is required.

這里先要搞清楚編碼(encode)和解碼(decode).下面是個人推測,沒有考證的解釋:

encode:編碼,將字符依據某種規則(字符集)解釋為一串數字
decode:解碼,將一串數字依據某種規則翻譯為字符

理解了編碼和解碼后,從一個字符串開始解析。

字符串str="中文",str是一串字符,通過str.getBytes()可以編碼成byte數組。通過new String(bytes)來解碼為字符串。下面是測試:

 1  @Test
 2     public void getEncod() throws UnsupportedEncodingException {
 3         String sysencod = System.getProperty("file.encoding");
 4         System.out.println("系統默認編碼:"+sysencod);
 5         String str = "中文";
 6         System.out.println("字符實例:"+str);
 7         System.out.println("===============getbytes無參:===============");
 8         byte[] bytes = str.getBytes();
 9         for (int i = 0; i < bytes.length; i++) {
10             System.out.print(bytes[i]);
11         }
12         System.out.println();
13         System.out.println("通過默認字符集,將字符數組解碼為字符:"+new String(bytes));
14         System.out.println("通過utf-8字符集,將字符數組解碼為字符:"+new String(bytes,"utf-8"));
15         System.out.println("通過gbk字符集,將字符數組解碼為字符:"+new String(bytes,"gbk"));
16         System.out.println("通過iso-8859-1字符集,將字符數組解碼為字符:"+new String(bytes,"iso-8859-1"));
17 
18 
19         System.out.println("===============getbytes(utf-8):===============");
20         byte[] bytes2 = str.getBytes("utf-8");
21         for (int i = 0; i < bytes.length; i++) {
22             System.out.print(bytes[i]);
23         }
24         System.out.println();
25         System.out.println("通過默認字符集,將字符數組解碼為字符:"+new String(bytes2));
26         System.out.println("通過utf-8字符集,將字符數組解碼為字符:"+new String(bytes2,"utf-8"));
27         System.out.println("通過gbk字符集,將字符數組解碼為字符:"+new String(bytes2,"gbk"));
28         System.out.println("通過iso-8859-1字符集,將字符數組解碼為字符:"+new String(bytes2,"iso-8859-1"));
29         System.out.println("===============getbytes(gbk):===============");
30         byte[] bytes3 = str.getBytes("gbk");
31         for (int i = 0; i < bytes.length; i++) {
32             System.out.print(bytes[i]);
33         }
34         System.out.println();
35         System.out.println("通過默認字符集,將字符數組解碼為字符:"+new String(bytes3));
36         System.out.println("通過utf-8字符集,將字符數組解碼為字符:"+new String(bytes3,"utf-8"));
37         System.out.println("通過gbk字符集,將字符數組解碼為字符:"+new String(bytes3,"gbk"));
38         System.out.println("通過iso-8859-1字符集,將字符數組解碼為字符:"+new String(bytes3,"iso-8859-1"));
39         System.out.println("===============getbytes(iso-8859-1):===============");
40         byte[] bytes4 = str.getBytes("iso-8859-1");
41         for (int i = 0; i < bytes.length; i++) {
42             System.out.print(bytes[i]);
43         }
44         System.out.println();
45         System.out.println("通過默認字符集,將字符數組解碼為字符:"+new String(bytes4));
46         System.out.println("通過utf-8字符集,將字符數組解碼為字符:"+new String(bytes4,"utf-8"));
47         System.out.println("通過gbk字符集,將字符數組解碼為字符:"+new String(bytes4,"gbk"));
48         System.out.println("通過iso-8859-1字符集,將字符數組解碼為字符:"+new String(bytes4,"iso-8859-1"));
49     }
View Code

結果:

奇詭的是,雖然getBytes打印的byte數組內容看起來是一樣的,但此編碼結構卻是不同的。並不是一串字符通過某種字符集編碼,再解碼就可以還原的。這要看該字符是屬於何種編碼。中文字符只有utf-8和gbk能夠存儲成功,別的編碼會出現漏碼像7位編碼之類的。而我要解決的就是中文亂碼問題。因此,中文編碼是關於utf-8和gbk的。

對於存儲於oracle的中文字符,采用iso-8859-1.因此,需要考慮的就是utf-8還是gbk轉儲為iso-8859-1.

經過測試,存儲的時候:p=new String(p.getBytes("gbk"),"iso-8859-1");而getBytes("utf-8")失敗。

查詢結果的時候:result = new String(str.getBytes("ISO-8859-1"),"gbk")可以將oracle的中文正常顯示。

附上我用oracle的字符集:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM