<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Mongoose House

    Technical Edition

    統(tǒng)計

    留言簿(4)

    積分與排名

    閱讀排行榜

    Java應(yīng)用系統(tǒng)亂碼問題分析

    前言

    本文章主要討論了在Java web系統(tǒng)中亂碼產(chǎn)生的內(nèi)在原理, 是認(rèn)識和解決亂碼問題的基礎(chǔ). 如果您對亂碼問題還沒有一個清晰的概念, 請嘗試閱讀本文. 另外, 本文也討論了最近流行的Ajax技術(shù)中的亂碼問題, 如果您在使用Ajax技術(shù)中遇到了亂碼, 本文對您也有一定的參考價值<1>。

    2006年5月30日

     

    為什么會出現(xiàn)亂碼

    我們都知道, 在馮·諾伊曼(Neumann János)<2>體系的計算機中, 任何數(shù)據(jù)都是以二進(jìn)制的形式存在的。我們在鍵盤上輸入以及我們在屏幕上看到的中文、日文、英文字符,最終都是內(nèi)存或者硬盤上的二進(jìn)制數(shù)據(jù)。那么,這種二進(jìn)制數(shù)據(jù)和屏幕上的中文、日文、英文字符之間相互的關(guān)系就需要通過一種映射來表達(dá),我們把這種關(guān)系稱之為“字符映射表”<3>。

     

    亂碼產(chǎn)生的原因

    圖 1-1 亂碼產(chǎn)生的原因

     

    譬如說, 字符集Shift_JIS規(guī)定“う”這個字保存到存儲介質(zhì)中為“82A4”;而字符集GBK規(guī)定存儲介質(zhì)中的“82A4”代表字符“鷛”。 因此,我們在日文系統(tǒng)<4>中把“あいうえお”這個字符串保存在某個文件中,然后這個文件被帶到一個中文系統(tǒng)上,讀取這個文件后就產(chǎn)生了亂碼,如圖1-1。

    在計算機的存儲介質(zhì)<5>中,保存的皆為二進(jìn)制的數(shù)據(jù)。計算機本身并沒有一種方法知道當(dāng)前的數(shù)據(jù)是日文的“う”還是中文的“鷛”。<6>

    任何一段文本(或者字符串)被保存到存儲介質(zhì)中的時候都需要有一個字符映射表與之相對應(yīng)。我們在處理文本(或者字符串)的時候需要清楚地知道當(dāng)前文本(或者字符串)的編碼方式<7>是什么。

     

    javac –encoding …

    Java作為現(xiàn)在最流行的一種開發(fā)語言運行在Java虛擬機上。 運行前,需要把Java的源代碼編譯成byte code,編譯后的byte code被Java虛擬機解釋執(zhí)行。<8>

    Java虛擬機認(rèn)為運行在其上的byte code的編碼方式是Unicode<9>,而Java源代碼以本地的(local)文本文件的形式存在,那么Java編譯器(通常是javac.exe)就需要知道當(dāng)前的Java源文件對應(yīng)的字符映射表,然后把其中的字符轉(zhuǎn)化為Unicode的字符。

    非常幸運地是,一般情況下,Java有一套很好的機制幫助我們完成了后面的種種編碼轉(zhuǎn)換工作,而使得編程人員不需要太在意代碼的字符集以便把注意力集中在應(yīng)用程序的邏輯實現(xiàn)上。

    假設(shè)我們使用Java編寫一個小程序,在控制臺打印“あいうえお”五個字符。(如圖2-1) 由于“任何一段文本(或者字符串)被保存到存儲介質(zhì)中的時候都需要有一個字符映射表與之相對應(yīng)”,所以當(dāng)我們使用文本編輯器(包括Eclipse等,非Microsoft Office)把一段文本保存到硬盤上的時候,我們需要指定當(dāng)前這段文本所對應(yīng)的編碼方式。(一般地,如果不指定字符映射表,文本編輯器會采用系統(tǒng)默認(rèn)的字符映射表保存文本。) 也就是說,我們在日文Windows XP下編寫的Java源代碼會采用MS932<4>這個字符映射表保存到文件中(如圖2-1的①處)。

     

     編寫、編譯并運行Java代碼

     

    圖 2-1 編寫、編譯并運行Java代碼

     

    因為Java虛擬機認(rèn)為運行在其上的byte code的編碼方式是Unicode(如圖2-1的②處),所以Java編譯器會把Java源代碼編譯成Unicode形式的byte code。但是因為計算機本身并沒有一種方法知道當(dāng)前Java源文件的編碼方式,所以,如果不指定編碼方式的話,默認(rèn)地,Java編譯器會采用系統(tǒng)默認(rèn)的字符映射表讀取Java源文件。即,如果在Windows XP日文版下編譯此Java程序,那么就會使用MS932格式轉(zhuǎn)化其中的字符串,如果在Windows XP中文版下編譯此Java程序,那么就會使用MS936格式轉(zhuǎn)化其中的字符串。如果把Windows XP日文版下編寫的Java源代碼拿到Windows XP中文版下編譯自然就會出現(xiàn)錯誤了。

    因此,Java編譯器(特指javac.exe)向我們提供了一個-encoding的參數(shù),我們可以使用-encoding告訴Java編譯器采用哪種字符映射表來讀取Java源代碼。

    (如圖2-1的③處)那么在控制臺上可以正確地顯示“あいうえお”又是為什么呢?Java的System.out.println函數(shù),默認(rèn)地采用當(dāng)前系統(tǒng)的默認(rèn)字符映射表來輸出字符串。即,在WindowsXP日文版下會把Unicode的“あいうえお”按照MS932的格式輸出出來;在WindowsXP中文版下會把Unicode的“あいうえお”按照MS936的格式輸出出來。所以,編譯后的Java byte code可以在任何系統(tǒng)上正確地運行。也就是Java所謂的“Write Once, Run Anywhere.”

    另外,我們因此也知道,如果使用System.out.println輸出的字符串是亂碼的話,也并不能說明此字符串是有問題的。

     

    和web相關(guān)的編碼問題

    在Java web系統(tǒng)中,我們主要使用HTTP協(xié)議在網(wǎng)絡(luò)上通訊。 我們把瀏覽器稱為HTTP客戶端,把web服務(wù)器稱為HTTP服務(wù)端。兩者通過請求(request)和響應(yīng)(response)的方式傳遞數(shù)據(jù)。

     

     Web中的編碼方式

     

    圖3-1 Web中的編碼方式

     

    設(shè)想在Windows XP日文版上使用IE瀏覽器提交“あいうえお”幾個字符,然后HTTP服務(wù)端再把這幾個字符打印在HTTP客戶端的屏幕上。(如圖3-1) 其中可能在五處發(fā)生了字符集的轉(zhuǎn)換,一處是輸入的時候,二處是把字符串通過網(wǎng)絡(luò)提交到服務(wù)器的時候,三處是在服務(wù)器端處理字符串的時候,四處是把字符串通過網(wǎng)絡(luò)返回給客戶端的時候,五處是在客戶端顯示的時候。

    因為HTTP協(xié)議是一個文本傳輸協(xié)議,所以通過HTTP協(xié)議在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)一定是有一個對應(yīng)的字符集的。一般地,這個字符集是ISO-8859-1<11>。所以在2處和4處“あいうえお”的編碼方式是ISO-8859-1。我們通過實驗也可以證明,在1處和5處是HTTP客戶端指定的編碼方式<28>,在3處是服務(wù)器轉(zhuǎn)碼后的編碼方式<29>。

    由于現(xiàn)有的HTTP客戶端和服務(wù)器端已經(jīng)幫我們很好的封裝了HTTP協(xié)議的實現(xiàn),所以一般我們在做Java Web Programming程序的時候不考慮在網(wǎng)上傳遞的數(shù)據(jù)格式。

     

    在Java web系統(tǒng)中指定編碼方式

    在Java web系統(tǒng)中, 我們遇到的最多的項目就是采用JSP和Servlet技術(shù)的項目了。那么,在使用JSP和Servlet技術(shù)的web系統(tǒng)中,設(shè)置字符集的地方可能有五處。 下面我們先來討論和響應(yīng)相關(guān)的四處。

    一、 pageEncoding<12>

    我們可以在JSP頁面上加入指令(directives)

    <%@page pageEncoding=“Shift_JIS”%>

    JSP在運行前會被JSP編譯器編譯成Servlet,然后服務(wù)器加載此Servlet處理客戶端請求。 JSP中,指令是傳遞給JSP編譯器的參數(shù),即告訴JSP編譯器如何編譯JSP。 Page指令中的pageEncoding屬性即告訴JSP編譯器使用的是哪種字符映射表來讀取當(dāng)前JSP文件的源代碼。<30>如果沒有指定pageEncoding屬性,默認(rèn)地,JSP編譯器采用當(dāng)前系統(tǒng)的默認(rèn)字符映射表來讀取JSP頁面。

     

     Page指令的pageEncoding屬性

     

    圖3-1 Page指令的pageEncoding屬性

    譬如,我們經(jīng)常遇到的在Windows下編寫的Java web應(yīng)用程序發(fā)布到Solaris后,JSP不能編譯,通常是由于沒有指定pageEncoding造成的。

    二、 ContentType

    另外,我們可以在JSP頁面上加入含有ContentType的page指令

    <%@ page contentType=“text/html; charset=Shift_JIS”%>

    這個指令的效果等同于

    response.setContentType(“text/html; charset=Shift_JIS”);

    達(dá)到的目的有兩個。

    其一,在響應(yīng)的HTTP文本中加入Content-type報頭(header)??蛻舳藭鶕?jù)Content-type來讀取網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)。<13>

    其二,通知web容器如何把文本(或者字符串)轉(zhuǎn)化為網(wǎng)絡(luò)上傳輸?shù)亩M(jìn)制數(shù)據(jù)。<14>

    需要注意的是,我們使一個字符串在網(wǎng)絡(luò)上傳輸和把一個字符串保存到文件中本質(zhì)上是相同的,我們都需要一個字符映射表來映射字符和byte之間的關(guān)系。

     

     關(guān)于設(shè)置ContentType的作用

     

    圖3-2 關(guān)于設(shè)置ContentType的作用

     

    假設(shè)我們需要把“あいうえお”這個字符串發(fā)送給客戶端,那么我們可以通過上面兩種方式(即page指令和response對象)設(shè)置ContentType為“Shift_JIS”。 設(shè)置后,服務(wù)器會認(rèn)為是“あいうえお”是使用“Shift_JIS”編碼的字符串,并且以此變?yōu)楸忍亓靼l(fā)送到客戶端。

    客戶端在接收到HTTP響應(yīng)后并不知道服務(wù)器端是“あいうえお”,它得到的只是一堆比特數(shù)據(jù),那么它會根據(jù)HTTP響應(yīng)的報頭Content-type中的設(shè)置,把這堆比特數(shù)據(jù)轉(zhuǎn)化為“あいうえお”。,<15>

    一、 Meta Data

    最后一個設(shè)置字符集的地方就是HTML頁面的meta標(biāo)簽。 一般地

    <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">

    這里設(shè)置的字符集是告訴瀏覽器如何顯示HTML頁面。<16>

     

     關(guān)于meta data的作用

     

    圖3-3 關(guān)于meta data的作用

     

    總結(jié), 對于客戶端頁面顯示亂碼,如果服務(wù)器端數(shù)據(jù)正常的話,那么可能是以上四種地方設(shè)置有誤。如果pageEncoding設(shè)置錯誤,一般表現(xiàn)為JSP頁面無法編譯,或者編譯后JSP頁面中固有的字符串不能正常顯示;如果Content Type設(shè)置錯誤,一般表現(xiàn)為JSP頁面全部或者大部分為亂碼,調(diào)整瀏覽器的顯示編碼格式后,仍然不能解決;如果meta data設(shè)置錯誤,一般表現(xiàn)為JSP頁面全部為亂碼,調(diào)整瀏覽器的顯示編碼格式后,可以解決。

    每種變量如果不設(shè)置,則采用缺省值。如果不設(shè)置pageEncoding,JSP編譯器采用當(dāng)前系統(tǒng)默認(rèn)的字符映射表來讀取JSP文件;如果不設(shè)置Content-type,則采用ISO-8859-1<17>來作為Content-Type。

     

    提交數(shù)據(jù)的編碼方式

    一般地,客戶端提交給服務(wù)器的數(shù)據(jù)有兩種形式,GET和POST。 使用GET方式提交數(shù)據(jù)的時候,HTTP消息中沒有報體(Message Body),提交的數(shù)據(jù)存在于URL中<18>;使用POST提交數(shù)據(jù)的時候, 提交的數(shù)據(jù)存在于HTTP消息的報體中。 (另外,最近比較流行使用XMLHtttpRequest對象提交數(shù)據(jù),我們將在下一節(jié)中討論。)

    無論以哪種方式提交數(shù)據(jù),這些數(shù)據(jù)都要經(jīng)過編碼和URL Encoding<19>兩個過程。

     

     URL Character Encoding

     

    圖4-1 URL Character Encoding<19>

     

    在服務(wù)端會做一遍上述編碼過程的逆過程,從而得到“あいうえお”。 那么,問題就是服務(wù)端如何知道客戶端傳遞過來的字符串使用什么編碼方式?

    首先,假設(shè)我們在頁面表單里輸入了“あいうえお”,那么HTTP客戶端(瀏覽器)會使用什么編碼方式對它進(jìn)行編碼?HTTP客戶端(瀏覽器)會使用當(dāng)前頁面的顯示字符集對它進(jìn)行編碼。

    顯示字符集是指顯示某個頁面的時候所使用的字符集。既不是meta中指定的字符集<20>,也非Content-type中指定的字符集。

    在Microsoft Internet Explorer中,顯示字符集可以在下面這里看到。

     

    image008

     

    圖4-2 IE的顯示字符集

     

    在Mozilla Firefox中,顯示字符集可以在下面這里看到。

     

     Firefox的顯示字符集

     

    圖4-3 Firefox的顯示字符集

     

    客戶端會根據(jù)當(dāng)前頁面的顯示字符集編碼當(dāng)前頁面上表單中的數(shù)據(jù),并提交到服務(wù)端。

    或者說,可以通過改變頁面的顯示字符集來改變提交數(shù)據(jù)的編碼方式。

    其次,當(dāng)數(shù)據(jù)提交到服務(wù)端,服務(wù)器端如何知道客戶端傳遞過來的數(shù)據(jù)是采用什么編碼方式?答案是因不同服務(wù)器不同而不同。

    對于Tomcat, Tomcat會認(rèn)為客戶端提交的數(shù)據(jù)全部采用ISO-8859-1的方式編碼,所以Tomcat會采用ISO-8859-1的形式解碼;而Weblogic會采用響應(yīng)客戶端頁面的編碼方式解碼。但是無論哪種服務(wù)器采用哪種方式,都不能保證是我們想要的!

    那么我們?nèi)绾蝸碇付ㄎ覀兿胍慕獯a方式呢?

    在Java web系統(tǒng)中,我們可以采用request.setEncoding(<encoding_str>)來指定客戶端的編碼方式。 這行代碼即告訴request對象,客戶端的編碼方式是<encoding_str>。由此,我們就可以保證客戶端提交的數(shù)據(jù)和服務(wù)器端接收的數(shù)據(jù)采用同樣的編碼方式。

     

    關(guān)于Ajax系統(tǒng)編碼方式的討論

    2005年,Ajax作為最熱門的名詞之一使使用Ajax技術(shù)的項目一下多起來。 因為初次使用這種技術(shù),所以其中最大的問題之一就是編碼問題。

    Ajax的核心是XMLHttpRequest對象??傮w來說, XMLHttpRequest對象是一個簡單的對象。 我們可以調(diào)用它的send方法向服務(wù)器端發(fā)送數(shù)據(jù),以及可以調(diào)用它的responseText和responseXML來接收從服務(wù)器端返回的數(shù)據(jù)。

    根據(jù)W3C的定義<21>, 我們使用XMLHttpRequest對象的send方法發(fā)送的數(shù)據(jù)總是為Unicode(UTF-8)的編碼方式;使用XMLHttpRequest對象的responseText接收的數(shù)據(jù)根據(jù)Content-type<22>中指定的不同而不同。使用XMLHttpRequest對象的responseXML接收的數(shù)據(jù)必須符合XML規(guī)范,且Content-type中的字符集必須和XML的字符集相同。譬如指定返回Shift_JIS編碼的XML數(shù)據(jù)。

    response.setContentType("text/xml;charset=Shift_JIS");

    response.getWriter().write("<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>");

    如果沒有指定XML的prolog, 則默認(rèn)編碼為UTF-8<23>。 所以必須指定Content-type也應(yīng)該為UTF-8<24>。

    我們在提交數(shù)據(jù)的編碼方式中討論過,使用表單提交數(shù)據(jù)需要通過兩個階段的編碼,一個是使用某種字符集編碼,然后再使用URL Character Encoding編碼。這樣做是因為在HTTP協(xié)議下網(wǎng)絡(luò)中傳輸?shù)氖荌SO-8859-1的字符,我們通過這種方式可以把任何字符集轉(zhuǎn)化為符合ISO-8859-1字符集的字符串。 但是,我們使用XMLHttpRequest提交數(shù)據(jù)的時候,就沒有URL Character Encoding這一步。

     

     沒有經(jīng)過URL Character Encoding的數(shù)據(jù)

     

    圖5-1沒有經(jīng)過URL Character Encoding的數(shù)據(jù)

     

    當(dāng)然,幸運地是現(xiàn)在的服務(wù)器都非常健壯,可以做上述操作的逆操作,這樣我們編寫的代碼還是可以運行的。但是這不是一個好習(xí)慣。

    一般地,我們使用Ajax技術(shù)的時候,需要手工的進(jìn)行URL Character Encoding。 有三個Javascript函數(shù)可以幫助我們做這一點。escape, encodeURI和encodeURIComponent<25>。推薦使用encodeURIComponent<26>。

     

    小結(jié)

    在Java系統(tǒng)中,因為底層(byte code)為UTF-8的,所以我們的程序采用什么樣的編碼方式跟操作系統(tǒng)并沒有什么關(guān)系。在Java web系統(tǒng)中,無論客戶端的操作系統(tǒng)或者服務(wù)器的操作系統(tǒng),只要能保證數(shù)據(jù)傳輸?shù)臅r候采用統(tǒng)一的編碼方式,那么就不會有亂碼問題出現(xiàn)。

    當(dāng)在某個特定的系統(tǒng)下發(fā)生亂碼時,我們需要判斷亂碼發(fā)生的地方。此時,使用一些HTTP分析工具<27>是一個好辦法。 有時候,我們使用一些服務(wù)器或者框架(framework),它們?yōu)槲覀冏隽艘恍┚幋a轉(zhuǎn)換的工作,這時候問題就變得復(fù)雜起來。解決這種問題有兩點,其一是本文中提交的基本原理,其二是這種服務(wù)器(或者框架)的特性。

    有時候我們開發(fā)的系統(tǒng)頁面非常復(fù)雜,在上面使用了框架(frame),Ajax甚至flash等技術(shù),這樣有可能導(dǎo)致在一個瀏覽器窗口中存在幾種編碼方式,這種情況是可能存在的,遇到亂碼問題就需要具體問題具體分析了。

     

    THE END

     

    參考

    <1> 對這篇文章感興趣的同學(xué)可以給我寫郵件

    <2> 馮·諾伊曼結(jié)構(gòu)也稱為普林斯頓結(jié)構(gòu),參考Wikipedia中關(guān)于“馮·諾伊曼結(jié)構(gòu)”的介紹

    <3> 參考INNA中關(guān)于的Character Sets的定義

    <4> 默認(rèn)在Windows XP日文版中系統(tǒng)的編碼方式為MS932,基本等同于IANA的Shift_JIS; 默認(rèn)在Windows XP中文版中系統(tǒng)的編碼方式為MS936,基本等同于IANA的GBK

    <5> 這里的存儲介質(zhì)指內(nèi)存中的變量,磁盤上的文件以及網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)等

    <6> 其實這種說法并不準(zhǔn)確,有些系統(tǒng)有默認(rèn)的編碼方式,譬如XML默認(rèn)編碼方式是UTF-8 (參考W3C中XML 1.0的規(guī)范文檔Extensible Markup Language (XML) 1.0 (Third Edition)的2.2 Characters);有些系統(tǒng)在字符串中加入了編碼方式,譬如郵件的標(biāo)題前面帶有“=?GB2312?”這樣制定的字符集(參考RFC2047的2. Syntax of encoded-words)

    <7> 下文中“編碼方式”,“字符映射表”,“字符集”均指同一個意思。

    <8> 參考Java虛擬機規(guī)范 —— The JavaTM Virtual Machine Specification

    <9> 參考Java虛擬機規(guī)范 2.1 Unicode

    <10> HTTP協(xié)議的描述在RFC2616

    <11> 根據(jù)RFC2616,HTTP協(xié)議是基于文本的協(xié)議,在HTTP層傳遞的是使用ISO-8859-1編碼的文本數(shù)據(jù)。關(guān)于這個問題的具體討論在我講的《Java Web Programming》中第一章第二節(jié)。

    <12> 本節(jié)內(nèi)容可以參考JavaServer Pages Specification。 目前最新版的JavaServer Pages Specification 2.1是JSR245

    <13> 在HTTP 1.0規(guī)范中, 如何確定網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)格式是采用Content-Type的,但是在HTTP 1.1規(guī)范中采用了Content-Language這個報頭。 另外,需要注意,編碼方式(字符集)和報頭Content-Encoding沒有關(guān)系。 參考RFC2616

    <14> 這句話不準(zhǔn)確,根據(jù)HTTP協(xié)議(RFC2616),HTTP協(xié)議是基于文本的協(xié)議,雖然在TCP/IP層傳遞的是比特流,但是在HTTP層傳遞的應(yīng)該是文本數(shù)據(jù)。所以這句話應(yīng)該說是在HTTP層傳遞的是使用ISO-8859-1編碼的文本數(shù)據(jù)。但是這樣會導(dǎo)致我們討論的問題復(fù)雜化,所以我們簡單認(rèn)為在網(wǎng)絡(luò)上傳輸?shù)氖潜忍亓?。進(jìn)一步討論可以給我寫郵件

    <15> 在客戶端接收到服務(wù)器端傳遞過來的數(shù)據(jù)的時候,實際上是文本數(shù)據(jù),采用ISO-8859-1編碼。 因為HTTP報頭完全符合ISO-8859-1的編碼格式,所以客戶端可以正確的讀取HTTP報頭中的信息。然后,客戶端會把HTTP報文按照ISO-8859-1轉(zhuǎn)化為比特數(shù)據(jù),接著把這些比特數(shù)據(jù)按照HTTP報頭中Content-type的設(shè)置轉(zhuǎn)化為相應(yīng)的字符。 我們在討論中為了簡單起見省略了這些步驟。

    <16> 如果有Content-type報頭,那么瀏覽器一般會優(yōu)先采用Content-type報頭中定義的字符集。

    <17> 對于Tomcat服務(wù)器

    <18> 雖然在RFC中沒有規(guī)定URL的最大長度,但是使用Internet Explorer支持的URL最大長度為2083個字符。 參考 KB208427

    <19> 關(guān)于URL Character Encoding 可以參考RFC1738 2.2節(jié)

    <20> 但是設(shè)置meta data會影響客戶端的字符集設(shè)置

    <21> 參考W3C的《The XMLHttpRequest Object

    <22> 此處為HTTP 1.0規(guī)范的定義, 在HTP 1.1規(guī)范中, 編碼方式定義在Content-Language中, 參考RFC2616

    <23> 參考W3C的《XML Base

    <24> 如果沒有指定,默認(rèn)的是ISO-8859-1

    <25> MSDN中對這三個函數(shù)的描述分別如下 escape, encodeURI encodeURIComponent

    <26> 在很多目前流行的Ajax框架中都使用這個函數(shù)。而仍然有些舊的系統(tǒng)在使用escape,我以為這是個誤區(qū)

    <27> 在我講的《Java Web Programming》中使用了一種叫Webscrab的工具,另外我寫這篇文章時使用一個叫做Http Analyzer的工具

    <28> 非客戶端操作系統(tǒng)默認(rèn)的編碼方式, 在“提交數(shù)據(jù)的編碼方式”一節(jié)中具體討論

    <29> 非服務(wù)器端操作系統(tǒng)的默認(rèn)編碼方式, 在“提交數(shù)據(jù)的編碼方式”一節(jié)中具體討論

    <30> 參考我的講座《Java Web Programming》中第六章第一節(jié)的內(nèi)容

    posted on 2009-08-27 11:04 Mongoose 閱讀(1577) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲av无码日韩av无码网站冲| 亚洲国产视频一区| 一级毛片人与动免费观看| 成人免费视频试看120秒| www.亚洲成在线| 全免费a级毛片免费看无码| 亚洲国产精品无码久久九九大片 | 亚洲一区二区三区无码影院| 精品视频免费在线| 亚洲乱码中文字幕手机在线| 国产日韩久久免费影院| 久久精品国产亚洲av麻| 51在线视频免费观看视频| 亚洲人成免费电影| 四虎影视在线永久免费看黄| 午夜在线免费视频 | 亚洲中文字幕视频国产| 国产亚洲精品免费视频播放| 亚洲成a人片77777老司机| 免费观看无遮挡www的小视频| 亚洲永久在线观看| 五月天婷亚洲天综合网精品偷| eeuss影院免费直达入口| 日韩亚洲Av人人夜夜澡人人爽 | 国产黄色片在线免费观看| 日韩精品无码免费视频| 亚洲va在线va天堂va不卡下载| 免费无码肉片在线观看| 在线视频亚洲一区| 久久九九亚洲精品| 最近2019中文免费字幕| 一级毛片在线免费视频| 亚洲黄色在线电影| 日本最新免费不卡二区在线| 国产在线精品一区免费香蕉| 亚洲噜噜噜噜噜影院在线播放| 四虎永久免费观看| 在线免费观看你懂的| 在线精品自拍亚洲第一区| 亚洲第一中文字幕| 亚洲 国产 图片|