自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java編碼問(wèn)題完全解決方案

開(kāi)發(fā) 后端
本文介紹了Java編碼是怎么回事,以及一些中文編碼的常見(jiàn)問(wèn)題及解決方案。對(duì)于Java語(yǔ)言來(lái)說(shuō),在其內(nèi)部使用的是UCS2編碼(2個(gè)字節(jié)的Unicode編碼)。這種編碼并不屬于某個(gè)語(yǔ)系的語(yǔ)言編碼,它實(shí)際上是一種編碼格式的世界語(yǔ)。

一、Java編碼是怎么回事?

對(duì)于使用中文以及其他非拉丁語(yǔ)系語(yǔ)言的開(kāi)發(fā)人員來(lái)說(shuō),經(jīng)常會(huì)遇到字符集編碼問(wèn)題。對(duì)于Java語(yǔ)言來(lái)說(shuō),在其內(nèi)部使用的是UCS2編碼(2個(gè)字節(jié)的Unicode編碼)。這種編碼并不屬于某個(gè)語(yǔ)系的語(yǔ)言編碼,它實(shí)際上是一種編碼格式的世界語(yǔ)。在這個(gè)世界上所有可以在計(jì)算機(jī)中使用的語(yǔ)言都有對(duì)應(yīng)的UCS2編碼。

正是因?yàn)镴ava采用了UCS2,因此,在Java中可以使用世界上任何國(guó)家的語(yǔ)言來(lái)為變量名、方法名、類(lèi)起名,如下面代碼如下:

  1. class 中國(guó)  
  2. {  
  3.     public String 雄起()  
  4.     {  
  5.          return "中國(guó)雄起";  
  6.     }  
  7. }  
  8.  
  9. 中國(guó) 祖國(guó) = new 中國(guó)();  
  10. System.out.println(祖國(guó).雄起());  

哈哈,是不是有點(diǎn)象“中文編程”。實(shí)際上,也可以使用其他的語(yǔ)言來(lái)編程,如下面用韓文和日文來(lái)定義個(gè)類(lèi):

  1. class 수퍼맨  
  2. {  
  3.     public void スーパーマン() {  }  

實(shí)際上,由于Java內(nèi)部使用的是UCS2編碼格式,因?yàn)?,Java并不關(guān)心所使用的是哪種語(yǔ)言,而只要這種語(yǔ)言在UCS2中有定義就可以。

在UCS2編碼中為不同國(guó)家的語(yǔ)言進(jìn)行了分頁(yè),這個(gè)分頁(yè)也叫“代碼頁(yè)”或“編碼頁(yè)”。中文根據(jù)包含中文字符的多少,分了很多代碼頁(yè),如cp935、cp936等,然而,這些都是在UCS2中的代碼頁(yè)名,而對(duì)于操作系統(tǒng)來(lái)說(shuō),如微軟的windows,一開(kāi)始的中文編碼為GB2312,后來(lái)擴(kuò)展成了GBK。其實(shí)GBK和cp936是完全等效的,用它們哪個(gè)都行。

二、Java編碼轉(zhuǎn)換

上面說(shuō)了這么多,在這一部分我們做一些編碼轉(zhuǎn)換,看看會(huì)發(fā)生什么事情。

先定義一個(gè)字符串變量:

  1. String gbk = "中國(guó)"// “中國(guó)”在Java內(nèi)部是以UCS2格式保存的  

用下面的語(yǔ)言輸出一定會(huì)輸出中文:

  1. System.out.println(gbk); 

實(shí)現(xiàn)上,當(dāng)我們從IDE輸入“中國(guó)”時(shí),用的是java源代碼文件保存的格式,一般是GBK,有時(shí)也可是utf-8,而在Java編譯程序時(shí),會(huì)不由分說(shuō)地將所有的編碼格式轉(zhuǎn)換成utf-8編碼,讀者可以用UltraEdit或其他的二進(jìn)制編輯器打開(kāi)上面的“中國(guó).class”,看看所生成的二進(jìn)制是否有utf-8的編碼(utf-8和ucs2之間的轉(zhuǎn)換非常容易,因?yàn)閡tf-8和ucs2之間是用公式進(jìn)行轉(zhuǎn)換的,而不是到代碼頁(yè)去查,這就相當(dāng)于將二進(jìn)制轉(zhuǎn)成16進(jìn)制一樣,4個(gè)字節(jié)一組)。如“中國(guó)”的utf-8編碼按著GBK解析就是“涓  浗”。如下圖所示。

utf-8編碼按著GBK解析 

如果使用下面的語(yǔ)言可以獲得“中國(guó)”的utf-8字節(jié),結(jié)果是6(一個(gè)漢字由3個(gè)字節(jié)組成)

  1. System.out.println(gbk.getBytes("utf-8").length); 

下面的代碼將輸出“涓  浗”。

  1. System.out.println(new String(gbk.getBytes("utf-8"), "gbk"));     

由于將“中國(guó)“的utf-8編碼格式按著gbk解析,所以會(huì)出現(xiàn)亂碼。

如果要返回中文的UCS2編碼,可以使用下面的代碼:

  1. System.out.println(gbk.getBytes("unicode")[2]);  
  2.  
  3. System.out.println(gbk.getBytes("unicode")[3]);  

前兩個(gè)字節(jié)是標(biāo)識(shí)位,要從第3個(gè)字節(jié)開(kāi)始。還有就是其他的語(yǔ)言使用的編碼的字節(jié)順序可能不同,如在C#中可以使用下面的代碼獲得“中國(guó)“的UCS2編碼:

  1. String s = "中";  
  2.  
  3. MessageBox.Show(ASCIIEncoding.Unicode.GetBytes(s)[0].ToString());  
  4.  
  5. MessageBox.Show(ASCIIEncoding.Unicode.GetBytes(s)[1].ToString());  

使用上面的java代碼獲得的“中“的16進(jìn)制UCS2編碼為4E2D,而使用C#獲得的相應(yīng)的ucs2編碼為2D4E,這只是C#和Java編碼內(nèi)部使用的問(wèn)題,并沒(méi)有什么關(guān)系。但在C#和Java互操作時(shí)要注意這一點(diǎn)。

如果使用下面的java編碼將獲得16進(jìn)制的“中”的GBK編碼:

  1. System.out.println(Integer.toHexString(0xff & xyz.getBytes("gbk")[0]));  
  2.  
  3. System.out.println(Integer.toHexString(0xff & xyz.getBytes("gbk")[1]));  

“中”的ucs2編碼為2D4E,GBK編碼為D6D0

讀者可訪問(wèn)如下的url自行查驗(yàn):

http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT

三、Java編碼相關(guān)的屬性文件

Java中的屬性文件只支持iso-8859-1編碼格式,因此,要想在屬性文件中保存中文,就必須使用UCS2編碼格式("uxxxx),因此,出現(xiàn)了很多將這種編碼轉(zhuǎn)換成可視編碼和工具,如Eclipse中的一些屬性文件編輯插件。

實(shí)際上,"uxxxx編碼格式在java和C#中都可以使用,如下面的語(yǔ)句所示:

  1. String name= ""u7528"u6237"u540d"u4e0d"u80fd"u4e3a"u7a7a" ;  
  2.  
  3. System.out.println(name);  

上面代碼將輸出“用戶名不能為空”的信息。將"uxxxx格式顯示成中文非常簡(jiǎn)單,那么如何將中文還原成"uxxxxx格式呢?下面的代碼完成了這個(gè)工作:

  1. String ss = "用戶名不能為空";  
  2. byte[] uncode = ss.getBytes("Unicode");  
  3. int x = 0xff;  
  4. String result ="";  
  5. for(int i= 2; i <  uncode.length; i++)  
  6. {  
  7.     if(i % 2 == 0) result += "\\u";  
  8.     String abc = Integer.toHexString(x & uncode[i]);              
  9.     result += abc.format("%2s", abc).replaceAll(" ""0");                 
  10. }  
  11. System.out.println(result); 

上面的代碼將輸出如下結(jié)果:

\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a

好了,現(xiàn)在可以利用這個(gè)技術(shù)來(lái)實(shí)現(xiàn)一個(gè)屬性文件編輯器了。

四、Web中的Java編碼問(wèn)題

大家碰到最多的編碼問(wèn)題就是在Web應(yīng)用中。先讓我們看看下面的程序:

  1. < !--  main.jsp  --> 
  2.  
  3.   < %@ page language="java"  pageEncoding="utf-8"%> 
  4.  
  5.   < html> 
  6.       < head> 
  7.  
  8.       < /head> 
  9.  
  10.       < body> 
  11.           < form action="servlet/MyPost" method="post"> 
  12.               < input type="text" name="user" /> 
  13.               < p/> 
  14.               < input type="submit"  value="提交"/> 
  15.           < /form> 
  16.  
  17.       < /body> 
  18.   < /html> 

下面是個(gè)Servlet:

  1. package servlet;  
  2.  
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9.  
  10. public class MyPost extends HttpServlet  
  11. {  
  12.  
  13.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  14.             throws ServletException, IOException  
  15.     {  
  16.         String user = request.getParameter("user");  
  17.         System.out.println(user);  
  18.     }  
  19. }  

如果中main.jsp中輸入中文后,向MyPost提交,在控制臺(tái)中會(huì)輸出“中国”,一看就是亂碼。如果將IE的當(dāng)前編碼設(shè)成其他的,如由utf-8改為gbk,仍然會(huì)出現(xiàn)亂碼,只是亂得不一樣而已。這是因?yàn)榭蛻舳颂峤粩?shù)據(jù)時(shí)是根據(jù)瀏覽器當(dāng)前的編碼格式來(lái)提交的,如瀏覽器當(dāng)前為gbk編碼,就以gbk編碼格式來(lái)提交。 這本身是不會(huì)出現(xiàn)亂碼的,問(wèn)題就出在Web服務(wù)器接收數(shù)據(jù)的時(shí)候,HttpServletRequest在將客戶端傳來(lái)的數(shù)據(jù)轉(zhuǎn)成ucs2碼上出了問(wèn)題。在默認(rèn)情況下,是按著iso-8859-1編碼格式來(lái)轉(zhuǎn)的,而這種編碼格式并不支持中文,所以也就無(wú)法正常顯示中文了,解決這個(gè)問(wèn)題的方法是用和客戶端瀏覽器當(dāng)前編碼格式一致的編碼來(lái)轉(zhuǎn)換,如果是utf-8,則在doPost方法中應(yīng)該用以下的語(yǔ)句來(lái)處理:

  1. request.setCharacterEncoding("utf-8"); 

為了對(duì)每一個(gè)Servlet都起作用,可以將上面的語(yǔ)句加到filter里。

另外,我們一般使用象MyEclipse一樣的IDE來(lái)編寫(xiě)jsp文件,這樣的工具會(huì)根據(jù)pageEncoding屬性將jsp文件保存成相應(yīng)的編碼格式,但如果要使用象記事本一樣的簡(jiǎn)單的編輯器來(lái)編寫(xiě)jsp文件,如果pageEncoding是utf-8,而在默認(rèn)時(shí),記事本會(huì)將文件保存成iso-8859-1(ascii)格式,但在myeclipse里,如果文件中有中文,它是不允許我們保存成不支持中文的編碼格式的,但記事本并不認(rèn)識(shí)jsp,因此,這時(shí)在ie中就無(wú)法正確顯示出中文了。除非用記事本將其保存在utf-8格式。如下圖:

用記事本將其保存在utf-8格式 

【編輯推薦】

  1. 使用Java截取字符串的方法
  2. 實(shí)現(xiàn)Java中對(duì)象比較的兩個(gè)方法
  3. 初學(xué)Java多線程:使用Synchronized塊同步方法
  4. 初學(xué)Java多線程:使用Synchronized關(guān)鍵字同步類(lèi)方法
  5. 初學(xué)Java多線程:從線程返回?cái)?shù)據(jù)的兩種方法
責(zé)任編輯:yangsai 來(lái)源: 真的有外星人嗎
相關(guān)推薦

2009-10-29 13:54:33

遠(yuǎn)程接入解決方案

2010-05-28 19:39:28

MySQL 編碼轉(zhuǎn)換

2024-05-09 15:00:38

Python編碼開(kāi)發(fā)

2009-09-28 11:14:15

2010-05-17 09:49:46

MySQL中文問(wèn)題

2011-03-02 14:56:56

FileZilla425問(wèn)題

2010-05-10 16:15:34

2019-10-08 16:05:19

Redis數(shù)據(jù)庫(kù)系統(tǒng)

2023-10-16 16:08:42

工業(yè) 4.0物聯(lián)網(wǎng)邊緣計(jì)算

2025-01-15 08:49:27

2012-05-09 10:08:41

跨機(jī)房

2022-03-31 10:25:20

物聯(lián)網(wǎng)工業(yè) 4.0大數(shù)據(jù)分析

2015-05-12 16:31:22

Elasticsear開(kāi)源分布式搜索引擎

2010-05-31 12:38:48

Nagios中文

2021-01-12 11:02:56

云計(jì)算云存儲(chǔ)技術(shù)云開(kāi)發(fā)

2021-01-12 11:13:11

云備份云原生云平臺(tái)

2024-11-08 13:47:35

中文亂碼配置

2012-05-27 16:21:31

IDC華為

2018-12-03 12:17:27

Semptian解決方案

2010-03-30 16:04:34

Linux Nginx
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)