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也用不了了