1. 程式人生 > 其它 >JavaWeb中編碼問題的解決辦法(在客戶端和伺服器之間傳入或響應資料後中文亂碼; cookie的亂碼問題) || Cookie和Session

JavaWeb中編碼問題的解決辦法(在客戶端和伺服器之間傳入或響應資料後中文亂碼; cookie的亂碼問題) || Cookie和Session

在JavaWeb中,解決中文編碼這個問題總結下來一共有有兩處

1.在Get或者Post請求中,攜帶有中文的時候可能會造成亂碼問題

在Tomcat中,對於POST和GET請求,都預設才有的ISO-8859-1的編碼方式.而該ISO-8859-1不支援中文,所以亂碼.
--------------------------------------------------------------------
解決方案:
  1:按照ISO-8859-1把亂碼恢復成二進位制形式
  byte[] data=username.getBytes("ISO-8859-1");
  2:再把二進位制形式的資料使用UTF-8重新編碼
  String username 
= new String(data,"UTF-8"); -------------------------------------------------------------------- 但是同樣上述程式碼也有一個問題, 獲取一個引數的時候需要使用兩行程式碼來轉碼,如果現在需要獲取N個引數,那麼就需要轉N次,出現了程式碼重複的嚴重問題. 解決方案:   針對於POST請求方式:   request.setCharacterEncoding("UTF-8");   注意:1:只對POST有效,2:必須放在獲取任意引數之前.
  針對於GET請求方式:   修改Tocmcat中的server.xml配置檔案中修改埠的元素,對GET方式的預設編碼.在開發中, 我們很少會用到並且不建議去修改Tomcat伺服器的server.xml配置檔案, 因為我們很少會用Get方式傳遞中文

2.對Cookie的操作的時候,我們常常也會遇到中文亂碼的問題

下面是對Cookie常用操作的複習與回顧,按照這個思路來說明下中文亂碼的問題

我們常見的Cookie的操作:
1:建立Cookie物件.
     Cookie cookie = new Cookie(String name,String value);
       引數:
          name:  該當前Cookie取一個唯一的名字.
          value: 儲存在Cookie的共享資料,只能是String型別.
     Cookie cookie = new Cookie("currentName","will");
2:把Cookie放入響應中,響應給瀏覽器,把共享的資料儲存在瀏覽器中. response.addCookie(cookie); 3:獲取Cookie以及獲取Cookie中的資料. 因為Cookie是客戶端技術,並且每一次請求都會攜帶,因此是存放在請求頭中,所以應該通過request去獲取. Cookie[] cs = req.getCookies(); 獲取當前Cookie的名字: String name = cookie物件.getName(); 獲取當前Cookie的值: String value= cookie物件.getValue(); 4:Cookie的中文問題. 在Cookie中屬性名和屬性值都不能使用中文.

 5:修改Cookie中指定屬性名的屬性值.
需求:修改Cookie cookie = new Cookie("currentName","will");
方式1:建立一個同名的新的Cookie.
Cookie c = new Cookie("currentName","Lucy");
方式2:獲取該Cookie物件,通過setValue方法,重新設定新的value值.
Cookie物件.setValue("新的值");
注意:別忘了,重新把該Cookie放入響應中:resp.addCookie(c);
6:Cookie的分類(會話Cookie和持久化Cookie):
會話Cookie: 關閉瀏覽器之後,Cookie就銷燬了. 預設情況.
持久化Cookie: Cookie可以儲存指定的時間段(3天,一週,一個月).
設定Cookie的最大存活時間: cookie物件.setMaxAge(int seconds);
seconds == 0: 刪除Cookie.
seconds < 0: 會話Cookie.
seconds > 0: 儲存指定的秒數
7:刪除Cookie: cookie物件.setMaxAge(0);




附:對session的複習

上面提到Cookie的使用,可以得知Cookie的問題和需要改進的地方

Cookie的缺陷:
    1):多個人使用同一臺電腦的時候,可以檢視瀏覽器的Cookie,不安全.
    2):Cookie儲存中文比較麻煩(得編碼,再解碼).
    3):Cookie的value是String型別,一個Cookie就只能儲存一個數據,如果需要儲存多個數據,就得死還有N個Cookie.
    4):一個站點對Cookie有限制:
      Cookie大小限制在4KB之內;
      一臺伺服器在一個客戶端最多儲存20個Cookie;
      一個瀏覽器最多可以儲存300個Cookie;
    5):在設計上就有問題,考慮生活中問題.
       Cookie是瀏覽器和伺服器之間資料互動的憑證.
       在生活中,我們是把識別資料儲存到服務端.
-------------------------->Session.

因此,引出了session的技術,值得注意的是:

Session是伺服器端技術,利用這個技術,伺服器在執行時可以為每一個使用者的瀏覽器建立一個其獨享的session物件,
由於session為使用者瀏覽器獨享,所以使用者在訪問伺服器的web資源時,可以把各自的資料放在各自的session中,當用戶再去訪問伺服器中的其它web資源時,
其它web資源再從使用者各自的session中取出資料為使用者服務

注意: Session其本質就是一個會話Cookie(瀏覽器關閉之後,Session就失效了).

對比下兩種技術的原理圖,就可以看出他們其中的差異

該圖為Cookie的原理圖

==============================================================================================================================

該圖為Session的原理圖

Session的操作:
1:建立和獲取Session物件.
  HttpSession session = request.getSession(true);如果當前請求中存在一個Session物件,就直接返回,如果不存在Session物件,就先建立一個再返回.
  HttpSession session = request.getSession(false);如果當前請求中存在一個Session物件,就直接返回,如果不存在Session物件,就返回null.
  HttpSession session = request.getSession();等價於HttpSession session = request.getSession(true);

2:往Session中儲存資料.
  session物件.setAttribute(String name,Object value);

3:從Session中取出資料.
  Object value = session物件.getAttribute(String key);

4:刪除Session(使用者登出登陸).
     1):刪除Session中指定屬性名的值.
        session物件.removeAttrbute("currentName");
     2):銷燬Session物件(Session中所有的屬性都不存在).
        session物件.invalidate();
5.Session的超時管理
  在超時時間之內,如果客戶端和服務端沒有互動(使用者的兩次操作之間不能超過該時間),則自動的銷燬Session.
  session物件.setMaxInactiveInterval(60 * 10);//超過10分鐘,銷燬Session.
  Tomcat伺服器的預設超時時間為:30分鐘,Tomcat一般在20多分鐘就銷燬了.
6.URL重寫.
   Session是一種特殊的Cookie,而瀏覽器可以禁用Cookie.
   此時,需要在每一個資源之後,手動的攜帶session的ID: /session/list;jsessionid=872870F9466CE7B3A11FD3B768FDD684
   但是我們手動來拼接session的ID的話,一個可以,要是每一個資源都需要拼接這一段的話, 屬實是是一個沒有技術含量的活,因此在 response 裡面有一個方法用於拼接jsessionid的。
   String url = response.encodeURL("/session/list");自動的在資源之後拼接;jsessionid=872870F9466CE7B3A11FD3B768FDD684
   注意:開發中都不會取消接受Cookie的.
Session的細節:
   1:一般的,我們儲存到Session中的屬性名稱,要唯一,我們習慣XXX_IN_SESSION:
     session物件.setAttribute("USER_IN_SESSION","will");
   2:若需要把多個數據存放到Session中,就得呼叫setAttribute方法N次,可以的.
     一般的,我們把需要儲存的資料,封裝成一個物件,然後在儲存到Session中.
     把使用者的資訊,封裝到user物件.
     session物件.setAttribute("USER_IN_SESSION",user物件);
   3:如果多臺伺服器之間需要共享Session,此時Session中的物件,必須實現java.io.Serializable(才能在網路上傳輸).
      序 列 化: 把物件資訊儲存為二進位制.
      反序列化: 把二進位制資訊恢復成物件.
   public class User implements java.io.Serializable{....}


注: 如果瀏覽器禁用Cookie的話, 那麼Session也用不了了