1. 程式人生 > >編碼(三):Java Web編碼問題

編碼(三):Java Web編碼問題

問題描述:

今天在測試產品的時候發現使用HttpUrlClient傳送POST表單資料,當資料量>=1M的時,後臺報錯,原因分析如下:

一、HTTP協議對資料大小的限制

根據RFC規定,HTTP1.1本身並沒有對GET和POST方法進行引數大小限制,但是不同的瀏覽器和WEB伺服器對資料大小會做限制,比如:

  1. 不同瀏覽器對URL長度的限制(字元)

    IE : 2803
    Firefox:65536
    Chrome:8182
    Safari:80000
    Opera:190000
    
  2. WEB伺服器對POST資料長度限制:

    Tomcat預設大小為2M,可以修改配置:maxPostSize="0",取消對資料大小的限制。
    

二、Tomcat預設大小為2M,為什麼超過1M資料就會報錯

經過檢視,發現在使用HttpUrlClient與後臺互動時,POST資料處理如下:

 1.使用 String data = "content=" + URLEncode.encode("XXXXX......", "utf-8"),對資料進行編碼;
 2.在傳遞資料時outputStream.writer(data.getByte("utf-8"));

這個過程進行了兩次UTF-8編碼使位元組數變大。問題解決了,但藉此機會瞭解下WEB中的編碼方式。以下內容學習總結與《深入分析Java WEB技術內幕》。

三、WEB中的編解碼

  1. URL編解碼:(URL中存在中文的情況)

    http:協議
    localhost:域名
    8080:埠
    /examples/servlets/servlet/屌絲男士:URI
    examples:ContextPath
    servlets/servlet/:ServeltPath
    屌絲男士:PageInfo
    name=屌絲男士:QueryString
    

    通過谷歌瀏覽器觀察:

    這裡寫圖片描述
    其中PageInfo採用了UTF-8編碼,而QueryString也採用了UTF-8編碼。至於為什麼會“%”,根據RFC3986可知瀏覽器編碼URL將非ASCII字元按照某種編碼格式程式設計16進位制數字後將每個16進製表示的位元組前加上“%”。
    a.不同的瀏覽器對 pageInfo 的編碼方式不同,Tomcat對URL中URI的解碼字符集是在connector中定義的,預設為ISO-8859-1。

    <Connector URIEncoding="UTF-8"/>
    

    b. QueryString的解碼字符集是在是在 Header 中 Content-Type 中,通過 charset 定義的,預設為 IOS-8859-1, 但是要使用 Content-Type 中定義的編碼,就要在 connector 中進行如下的設定:

    <Connector useBodyEncodingForURI="true"/> 
    

    URL 的編碼和解碼過程比較複雜,並不都由我們自己能完全控制,所以儘量在 URL 中使用非 ASCII 字元。

  2. POST 表單的編解碼

    POST 表單型別的引數傳遞方式與 QueryStirng 方式不同,是通過 HTTP Body 方式傳遞到伺服器端的,它根據 Content-Type 中的 charset 規定的格式進行編碼,在伺服器端也通過 Content-Type 中對字元編碼方式進行解碼。

  3. HTTP Body 中的編解碼

    響應的內容通過 Header 中的 Content-Type 返回客戶端,瀏覽器通過 Content-Type 的 charset 進行解碼。如果返回的 Content-Type 中沒有設定 charset 值,那麼瀏覽器將根據 HTML 的

     <meta HTTP-equiv="Content-Type" content="text/html; charset=utf-8" />
    

    來進行解碼。