日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

第三章 深入分析Java Web中的中文编码问题

發(fā)布時(shí)間:2025/3/15 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第三章 深入分析Java Web中的中文编码问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

3.1 幾種常見的編碼格式

  3.1.1 為什么要編碼

  一個(gè)字節(jié) byte只能表示0~255個(gè)符號(hào),要表示更多的字符,需要編碼。

  3.1.2 如何翻譯

  ASCII碼:有128個(gè),用一個(gè)字節(jié)的低7位表示。

  ISO-8859-1,能表示256個(gè),是單字節(jié)編碼。

  GB2312: 雙字節(jié)編碼,

  GBK:是對(duì)GB2312的擴(kuò)展,加入更多漢字,和GB2312兼容,BG2312編碼的漢字可以用GBK來解碼,不會(huì)亂碼。

  GB18030:

? ? ? ? ??

? ? ? ? UTF-16:Unicode(統(tǒng)一碼),ISO創(chuàng)建的全新的超語言字典。Unicode是JAVA和XML基礎(chǔ)。 注意: Unicode是編碼,也就是碼和漢字(或其他國家語言)的對(duì)應(yīng)關(guān)系。但是具體如何把這些編碼存儲(chǔ),則要采取不同的編碼方式,比如UTF-16和UTF-8。UTF-16就用固定兩個(gè)字節(jié)表示一個(gè)UNicode編碼。因?yàn)槭枪潭▋蓚€(gè)字節(jié)的長度,所以操作起來很簡(jiǎn)單,這也是JAVA以UTF-16作為字符的內(nèi)存存儲(chǔ)格式的原因。

? ? ? ? UTF-8: UTF的缺點(diǎn)是浪費(fèi),因?yàn)楹芏嘧址靡粋€(gè)字節(jié)就夠了,用不上兩個(gè)字節(jié)。

? ? ? ? UTF-8的編碼規(guī)則: ?如果一個(gè)字節(jié)最高位為0,XXX

            如果一個(gè)字節(jié)以11開頭,XXX

           ? ? ?如果一個(gè)字節(jié)以10開頭,XXX? ?

3.2 在JAVA中需要編碼的場(chǎng)景

? ? ?什么場(chǎng)合需要編碼

  3.2.1 在I/O操作中存在的編碼

    在字符到字節(jié)或從字節(jié)到字符的轉(zhuǎn)換,而這種轉(zhuǎn)換的場(chǎng)景主要是I/O. ?I/O包括磁盤和網(wǎng)絡(luò)兩種I/O.

    Reader類是在JAVA IO讀字符的父類,而inputstream類是讀字節(jié)的父類,InputStreamReader類就是關(guān)聯(lián)字節(jié)到字符的橋梁,字節(jié)到字符的轉(zhuǎn)換,而對(duì)具體字節(jié)到字符的編碼實(shí)現(xiàn),它又委托StreamDecoder去做,解碼過程中必須制定Charset,如果沒有制定,則將使用本地環(huán)境中的默認(rèn)字符集,如在中文環(huán)境中使用GBK。? ? ?

package ioTest;import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException;public class decodeTest {public static void main(String[] args) {String file = "XXX.txt";String charset = "UTF-8";try {FileOutputStream outputStream = new FileOutputStream(file);try {OutputStreamWriter writer = new OutputStreamWriter(outputStream, charset);try {writer.write("要保存的中文字符");} catch (IOException e) {// TODO Auto-generated catch block e.printStackTrace();}} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch block e.printStackTrace();}} catch (FileNotFoundException e) {// TODO Auto-generated catch block e.printStackTrace();}finally{writer.close();}} }

  3.2.2 在內(nèi)存操作中編碼

字節(jié)和字符轉(zhuǎn)換:

String s = "lfdasjlfjasljfasfa"; byte[] b = s.getBytes("UTF-8"); String n = new String(b, "UTF-8");

byte[] 和 char[]之間編碼和解碼:

String string = "fsdfsd"; Charset chars = Charset.forName("UTF-9"); ByteBuffer byteBuffer = chars.encode(string); CharBuffer charBuffer = chars.decode(byteBuffer);

3.3 在JAVA中如何編碼

  3.3.1 按照ISO-8859-1編碼

  3.3.2 按照GB2312編碼

  3.3.3 按照GBK編碼

  3.3.4 按照UTF-16編碼

  3.3.5 按照UTF-8編碼

  3.3.6 編碼UTF-8編碼代碼片段

  3.3.7 幾種編碼格式的比較

  GBK是對(duì)GB2312擴(kuò)展,可以表示所有的漢字。

? ? ? ?UTF-8比UTF-16更適合網(wǎng)絡(luò)傳輸

3.4 在JAVA web中編解碼

?

http請(qǐng)求過程中,存在編碼的地方是:

?

? ? ? ? ? ? ? 前段發(fā)過啦來的URL, cookie, ?Parameters。

?

    服務(wù)器接收到HTTP請(qǐng)求后,要解析HTTP,其中URL,cookie和POST表單參數(shù)需要解碼。

?

    服務(wù)器可能讀網(wǎng)絡(luò)和本地的文件和DB,可能存在編碼問題。

?

    當(dāng)servlet處理完所有請(qǐng)求后,需要將這些數(shù)據(jù)再編碼,發(fā)送給瀏覽器。

?

  ?3.4.1 URL的編解碼

    URL可能存在中文,所以需要編碼。

    瀏覽器編碼URL是將非ASCII字符按照某種編碼格式編碼成16進(jìn)制數(shù)字后將每個(gè)16進(jìn)制表示的字符前加上%。

    瀏覽器可以設(shè)置編碼格式。

    Tomcat是如何解碼的?

? ? ? ? ? ? ? ? ?’URL的URI部分進(jìn)行解碼的字符集是在<Connector URIEncodeing="UTF-8">里設(shè)置的。

     ? ?QueryString的解析過程:GET方式HTTP請(qǐng)求的querystring和POST方式HTTP請(qǐng)求的表單參數(shù)都是作為parameters保存的,都通過request.getParameter();

         ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?queryString的解碼字符集是在哪定義的呢? 是在HTTP的header的contentType或者是默認(rèn)的ISO-8859-1,如果要用HTTP的header中

                 中定義的編碼需要設(shè)置<Connector URIEncoding="UTF-8" ? ? ?useBodyEncodingForURI='true'>

    

?

  3.4.2 HTTP Header的編解碼

  除了上面的URL外,還可能在header中傳遞其他參數(shù),如cookie,redirectPath等。這些用戶設(shè)置的值也可能存在編碼問題。

? ? ? ?對(duì)Header的解碼是在調(diào)用request.getHeader()時(shí)進(jìn)行的。默認(rèn)是按照ISO-8859-1,如果header中有非ASCII,會(huì)亂碼。

? ? ? ?如果要用header傳遞中文,可以傳之前編碼,然后解碼:

    1、客戶端
    method.addRequestHeader("hello",URLEncoder.encode("中文","UTF-8"));
    2、服務(wù)器
    value=URLDecoder.decode(value);

  3.4.3 POST表單的編解碼

    POST表單提交的參數(shù)的解碼是在第一次調(diào)用request.getParameter時(shí)發(fā)生的,與queryString不同,是通過HTTP的body傳遞的,當(dāng)提交表單的時(shí)候,根據(jù)ContentType的charset編碼格式對(duì)表單中填入的參數(shù)編碼,然后提交到服務(wù)器,在服務(wù)器端也用contentType來解碼。這個(gè)編碼、解碼的字符集使我們自己設(shè)置的。

? ? ? ? ? ? ? 注意一定要在第一次調(diào)request.getParameter方法之前就設(shè)置request.setCharacterEncoding(charset), 否則會(huì)亂碼。

  3.4.4 HTTP BODY的編解碼

? ? ? ? ? ? ?response.setCharacterEcoding可以設(shè)置編碼方式,覆蓋request.getCharacterEncoding的值,并且通過contentType返回給客戶端。瀏覽器根據(jù)content-Type解碼;如果么有這個(gè)值,按照HTML中的charset來解碼。

? ? ? ? ? ? ?和JDBC的編碼方式要一致。

3.5 在JS中的編碼問題

  3.5.1 外部引入JS文件

? ? ? ? ? 如何js文件本身的編碼和JS中使用的字符編碼不一致,可能就有亂碼。比如*.js文件是UTF-8,而頁面是GBK,就會(huì)有亂碼問題。

  3.5.2 JS的URL編碼

  Ajax的http_request('get', url, ture)調(diào)用,URL在IE下用OS的默認(rèn)編碼,在Firefox下是UTF-8編碼。

  JS有三個(gè)函數(shù)是和編碼解碼相關(guān)的。

? ? ? ? JAVA是如何來解碼的?JAVA端處理URL編碼、解碼有連個(gè)類: ? 分別是Java.net.URLEncoder和java.net.URLDecoder

  3.5.3 其他需要編碼的地方

3.6 常見問題分析

  3.6.1 中文變成了看不懂的字符

    解碼和編碼用的字符集不一樣,就會(huì)出現(xiàn)亂碼。

  3.6.2 一個(gè)漢字變成一個(gè)問號(hào)

    ISO-8859-1遇到不認(rèn)識(shí)的用3F表示,是問號(hào)。

  3.6.3 一個(gè)漢字變成兩個(gè)問號(hào)

  3.6.4 一種不正常的正確編碼

3.7 一種繁簡(jiǎn)轉(zhuǎn)換的實(shí)現(xiàn)方式

3.8 總結(jié)

轉(zhuǎn)載于:https://www.cnblogs.com/liufei1983/p/7384317.html

總結(jié)

以上是生活随笔為你收集整理的第三章 深入分析Java Web中的中文编码问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。