java編碼,亂碼問題詳解

來源:互聯網
上載者:User

標籤:編碼   中文   stream   擷取   簡單   locate   控制字元   返回結果   writer   

 

一、常見的編碼格式1.ASCII

  基礎編碼,英文和西歐字元。

  用一個位元組的低7位表示,一共128個。

  0~13是控制字元如換行、斷行符號、刪除等,32~126是列印字元,鍵盤輸入。

2.IOS-8859-1

  ASCII的擴充。

  用一個位元組表示,一共256個。

3.GB2312

  中文編碼字元集。

  用兩個位元組表示,A1~A9是符號區,一共682個;B0~F7是漢字區,一共6763個。

  編碼需要查詢對應碼錶,效率略低。

4.GBK

  GB2312的擴充,能夠相容GB2312。

  用兩個位元組表示,一共23940個碼位,表示21003個漢字。

  編碼需要查詢對應碼錶,效率略低。

5.UTF-16

  UTF-16具體定義了Unicode字元在電腦的存取方法。

  用兩個位元組表示Unicode的轉化格式。

  定長的展示方法,每兩個位元組表示一個字元,轉化效率高,記憶體和硬碟多用此編碼(JAVA記憶體儲存格式UTF-16)。

  採用順序編碼,不能對單個字元的編碼進行校正,如果損壞,後面的碼值都會受影響。

6.UTF-8

  UTF-8具體定義了Unicode字元在電腦的存取方法。

  用1-6個位元組組成一個字元,漢字採用三個位元組表示。

  變長的展示方法,每個編碼地區有不同的字碼長度。

  網路傳輸中很大一部分字元用一個位元組就可以展示,UTF-16正常化的全部轉為了兩個位元組,對於這些字元UTF-8隻需要一個位元組。

  UTF-8如果中間一個碼值損壞,後面的碼值並不受影響。

  相對於UTF-16,UTF-8有傳輸中資源佔用小,資料更安全的優勢,更適合網路傳輸,但UTF-16的編碼規則相對簡單,編碼效率更高,適合本地記憶體和磁碟。

二、常見JAVA編碼API1.I/O  
InputStreamReader isr = new InputStreamReader(inputStream,"utf-8");Charset StreamDecoderOutputStreamWriter osw = new OutputStreamWriter(outputStream,"utf-8");Charset StreamEncoder
2.記憶體操作

字元與位元組的轉換:   

//String
String s = "中文字元";byte[] b = s.getBytes("UTF-8");String s1 = new String(b,"UTF-8");

//Charset
Charset charset = Charset.forName("UTF-8");
ByteBuffer byteBuffer = charset.encode(string);
CharBuffer charBuffer = charset.decode(byteBuffer);

//char和byte的軟轉換,將一個16bit的char拆分成兩個8bit的byte來顯示,實際值並沒有被轉換。
ByteBuffer heapByteBuffer = ByteBuffer.allocate(1024);
ByteBuffer byteBuffer = heapByteBuffer.putChar(c);
三、Java Web中涉及的編解碼1.URL編解碼

PathInfo中文問題:

配置tomcat的server.xml:

<Connector URIEncoding="UTF-8"/>

QueryString中文問題:

QueryString是通過HTTP中的Header傳到背景,他的解碼字元集預設是ISO-8859-1,

也可以通過Header的ContentType中的Charset來定義。

如何確定後端調取了ContentType中的字元集,需要在server.xml中配置(這個配置只針對QueryString有效):

<Connector useBodyEncodingForURI="true"/>

 

2.HTTP Header的編解碼

針對Header中的其他參數,比如Cookie,redirectPath等。

盡量不要傳遞非ASCII字元,如果必須,在傳遞之前用下面的API進行編碼再傳遞:

org.apache.catalina.util.URLEncoder

3.POST表單的編解碼

用戶端擷取參數為亂碼後的解決思路:

  1.將POST改為get,查看瀏覽器端是否有問題。

  2.後端request.geCharacterEncdoing返回結果是否是預期編碼。

//在第一次使用request.getParameter之前使用request.setCharacterEncoding(charset);

 

4.HTTP BODY的編解碼

主要闡述從後台到前台的編解碼:

//對返回前台的資料進行編碼,前台會首先根據這個值進行解碼response.setCharacterEncoding(charset);
<!-- 如果後台沒有設定,會根據頁面中的charset來解碼,如果頁面也有設定則用預設編碼來解碼 --><meta HTTP-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<!-- JDBC讀寫資料時要和資料的內建編碼保持一致 -->url="jdbc:mysql://localhost:3306/DB?useUnicode=true&characterEncoding=UTF-8"
四、JS的編碼問題1.外部引入js檔案
<!-- 瀏覽器會按照charset的設定來解析這個js檔案,如果沒有設定則預設按照當前頁面的的編碼設定來解析js檔案 --><script src="de/mo/demo.js" charset="gbk"></script>
2.js的URL編碼
//對url根據UTF-8進行編碼和解碼,除了一些特殊字元"!""#""$""&""‘""("")""*""+"",""-"".""/"":"";""=""?""@""_""~""0-9""a-z""A-Z"

//編碼結果在每個碼值前加一個"%"
encodeURI("http://localhost:8080/examples/servlets/servlet/來吧昆特牌吧孫子?inviter=傑洛特");
decodeURI("**編碼內容**");
//對url根據UTF-8進行編碼和解碼,相對於encodeURI,它更加的徹底。排除的特殊字元為"!""‘""("")""*""-"".""_""~""0-9""a-z""A-Z"
//編碼結果在每個碼值前加一個"%"
//它排除的字元比encodeURI更少,通常用於將URL作為參數的URL的編碼,如樣本如果不將參數URL中的&進行編碼會影響到整個URL的完整性
"http://localhost/servlet?ref=" + encodeURIComponent("http://localhost:8080/examples/servlets/servlet/來吧昆特牌吧孫子?inviter=傑洛特&inviter=葉奈法");
decodeURIComponent("**編碼內容**");
 

 

3.後端接收時解碼

後端處理URL編解碼靠的是 java.net.URLEncoder和java.net.URLDecoder這兩個類。

後端對的對URL的編碼同樣也有排除的特殊字元,與前端的encodeURIComponent相對應。

//後端直接擷取傳過來的URL參數會自動解碼
//如果沒有提前設定request.setCharacterEncoding()很容易出現編碼不同而導致的亂碼
request.getParameter();

//另一種方式是通過前台js對URL進行兩次編碼,後台不管通過什麼進行第一次解碼,都能得到正確的UTF-8編碼,前台代碼如下
encodeURIComponent(encodeURIComponent(url));
//第一次編碼的結果(例如:%E2%A7)的百分比符號,會在第二次編碼後將%變成%25(例如:%25E2%25A7)
//後台在執行request.getParameter()的時候會自動解碼,不管當前容器的編碼是什麼得到的是正確的UTF-8編碼(例如:%E2%A7)

 

五、其他需要編碼的地方1.xml

<?xml version="1.0" encoding="UTF-8"?>

2.Velocity

services.VelocityService.input.encoding=UTF-8

3.JSP

<%@page contentType="text/html;charset=UTF-8"%>

 

註:本文是對“《深入分析Java Web技術內幕》許令波 著” 一書的相關內容的總結

java編碼,亂碼問題詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.