http連續請求中Session丟失問題解決方案彙總
先說遇到的問題:同一套介面,iOS端的APP可以正常使用而Android端的APP不能使用(可以登入成功)。
初步除錯發現:Android端的APP登入成功後,後續的訪問取不到登入時儲存在session中的使用者資訊,而iOS是可以取到session中使用者資訊。
下面是筆者解決該問題的過程總結:
先簡單說一下HTTP請求中的Session機制:Session資料儲存在伺服器端,SessionID儲存在客戶端的Cookies中(關閉瀏覽器時過期)。當客戶端向伺服器傳送的HTTP請求時,SessionID通過Cookies被髮送到伺服器,伺服器端根據Cookies中的SessionID獲取獲取此使用者的Session資訊。
回過頭說筆者遇到的問題,Android端的APP登陸後Session丟失的問題,正是因為Android客戶端在呼叫介面的時候,每次請求都是單獨發起的請求,所以沒有共享同一個Session。而iOS端可用,應該是iOS開發人員自己做了處理,因為筆者是做Java開發的,這個就不深入了。
現在的問題就簡化為:如何使同一個客戶端的多次請求都共享伺服器端的同一個Session。上網找資料後發現解決辦法有兩個:
1、每次請求中攜帶SessionID(儲存在Cookies中)
Java模擬傳送請求時加入下面一行程式碼:
conn.setRequestProperty("Cookie", "JSESSIONID=A399BA4C94EBF00534F5F444B07D30A3");
Java傳送post請求示例程式碼:
<span style="white-space:pre"> </span>/** * 向指定 URL 傳送POST方法的請求 * * @param url * 傳送請求的 URL * @param param * 請求引數,請求引數應該是 name1=value1&name2=value2 的形式。 * @return 所代表遠端資源的響應結果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 開啟和URL之間的連線 URLConnection conn = realUrl.openConnection(); // 設定通用的請求屬性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 將Session資訊放入請求攜帶的Cookies中 conn.setRequestProperty("Cookie", "JSESSIONID=A399BA4C94EBF00534F5F444B07D30A3"); // 傳送POST請求必須設定如下兩行 conn.setDoOutput(true); conn.setDoInput(true); // 獲取URLConnection物件對應的輸出流 out = new PrintWriter(conn.getOutputStream()); // 傳送請求引數 out.print(param); // flush輸出流的緩衝 out.flush(); // 定義BufferedReader輸入流來讀取URL的響應 in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("傳送 POST 請求出現異常!" + e); e.printStackTrace(); } // 使用finally塊來關閉輸出流、輸入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; }
2、在請求URL中加入;jsessionid=F8DA665F7A45AFD63F527CA49C3A67C8
注意:這裡並不是作為引數加到URL中,而是在?之前加的
例如:http://localhost:8080/aaa/bbb.jsp;jsessionid=saldjfsdflsaeir234?para=1
以上兩種方法都可以有效解決Session丟失問題,筆者採用的是第一種,第二種也親測可用。
本文的方法都是客戶端修改請求程式碼,還有另一種方法不用客戶端更改請求程式碼,只需要伺服器端做出修改,有興趣的話可以請檢視筆者另一篇博文:Java根據sessionId獲取Session物件。