Android -- 與WEB互動在同一個會話Session中通訊
Session與Cookie
Cookie和Session都為了用來儲存狀態資訊,都是儲存客戶端狀態的機制,它們都是為了解決HTTP無狀態的問題而所做的努力。
Session可以用Cookie來實現,也可以用URL回寫的機制來實現。
Cookie和Session有以下明顯的不同點:
1)Cookie將狀態儲存在客戶端,Session將狀態儲存在伺服器端;
2)Cookies是伺服器在本地機器上儲存的小段文字並隨每一個請求傳送至同一個伺服器。網路伺服器用HTTP頭向客戶端傳送cookies,在客戶終端,瀏覽器解析這些cookies並將它們儲存為一個本地檔案,它會自動將同一伺服器的任何請求縛上這些cookies。
3)Session是針對每一個使用者的,變數的值儲存在伺服器上,用一個sessionID來區分是不同使用者session變數,這個值是通過使用者的瀏覽器在訪問的時候返回給伺服器,當客戶禁用cookie時,這個值也可能設定為由get來返回給伺服器;
4)就安全性來說:當你訪問一個使用session 的站點,同時在自己機器上建立一個cookie,建議在伺服器端的SESSION機制更安全些.因為它不會任意讀取客戶儲存的資訊。
Session機制
Session機制是一種伺服器端的機制,伺服器使用一種類似於雜湊表的結構(也可能就是使用雜湊表)來儲存資訊。
當程式需要為某個客戶端的請求建立一個session的時候,伺服器首先檢查這個客戶端的請求裡是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端建立過session,伺服器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端建立一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個
session id將被在本次響應中返回給客戶端儲存。
Session的實現方式
1)使用Cookie來實現
伺服器給每個Session分配一個唯一的JSESSIONID,並通過Cookie傳送給客戶端。
當客戶端發起新的請求的時候,將在Cookie頭中攜帶這個JSESSIONID。這樣伺服器能夠找到這個客戶端對應的Session。
2)使用URL回顯來實現
URL回寫是指伺服器在傳送給瀏覽器頁面的所有連結中都攜帶JSESSIONID的引數,這樣客戶端點選任何一個連結都會把JSESSIONID帶給伺服器。
如果直接在瀏覽器中輸入url來請求資源,Session是匹配不到的。
Tomcat對 Session的實現,是一開始同時使用Cookie和URL回寫機制,如果發現客戶端支援Cookie,就繼續使用Cookie,停止使用URL回寫。如果發現Cookie被禁用,就一直使用URL回寫。jsp開發處理到Session的時候,對頁面中的連結記得使用
response.encodeURL() 。
手機端與伺服器互動沒有實現在同一session下?
原因很簡單,就是因為android手機端在訪問web伺服器時,沒有給http請求頭部設定sessionID,而使用web瀏覽器作為客戶端訪問伺服器時,在客戶端每次發起請求的時候,都會將互動中的sessionID:JSESSIONID設定在Cookie頭中攜帶過去,伺服器根據這個sessionID獲取對應的Session,而不是重新建立一個新Session(除了這個Session失效)。
Code(1) HttpURLConnection實現
複製程式碼
URL url = new URL(requrl);
HttpURLConnection con= (HttpURLConnection) url.openConnection();
// 取得sessionid.
String cookieval = con.getHeaderField("set-cookie");
String sessionid;
if(cookieval != null) {
sessionid = cookieval.substring(0, cookieval.indexOf(";"));
}
//sessionid值格式:JSESSIONID=AD5F5C9EEB16C71EC3725DBF209F6178,是鍵值對,不是單指值
傳送設定cookie:
URL url = new URL(requrl);
HttpURLConnectioncon= (HttpURLConnection) url.openConnection();
if(sessionid != null) {
con.setRequestProperty("cookie", sessionid);
}
複製程式碼
Code(2) HttpClient 單例模式實現
只要存在一個HttpClient物件就可以了,這個HttpClient物件中就包含得有Cookie資訊。
我在工程中是使用的單例模式實現的:
複製程式碼
public class Client {
private static HttpClient instance = null;
private Client() {
}
public static HttpClient getInstance() {
if (instance == null) {
return instance = new DefaultHttpClient();
} else {
return instance;
}
}
}
複製程式碼
複製程式碼
class myThread extends Thread {
@Override
public void run() {
try {
HttpClient client = Client.getInstance();
String path = "http://192.168.1.4/zxx/test.php";
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000"));
httpPost.setEntity(new UrlEncodedFormEntity(param, "utf-8"));
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}finally
{
}
super.run();
}
}
class myThread2 extends Thread {
@Override
public void run() {
try {
HttpClient client = Client.getInstance();
String path = "http://192.168.1.4/zxx/test1.php";
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000"));
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}
super.run();
}
}
複製程式碼
兩個執行緒中就可以使用同一個cookie訪問了。
Code(3) SeesionId Url傳遞實現
通過將SessionId的值通過url傳遞到想繼續在同一會話中訪問的頁面。
php程式碼:test2.php
複製程式碼
<?php
session_start();
header("Content-type:text/html;charset=utf-8");
if(isset($_POST['phonenumber']))
{
$phone = $_POST['phonenumber'];
if(!isset($_SESSION['phone']))
{
$time=time()+60*10*10;//100分鐘
$_SESSION['phone'] = $phone;
echo session_id();
}
else
echo "POST phone already exist";
}
if(isset($_GET['phonenumber']))
{
$phone = $_GET['phonenumber'];
if(!isset($_SESSION['phone']))
{
$time=time()+60*10*10;//100分鐘
$_SESSION['phone'] = $phone;
echo session_id();
}
else
echo "GET phone already exist";
}
?>
複製程式碼
test3.php
複製程式碼
Session_id($_GET['id']);
session_start();
header("Content-type:text/html;charset=utf-8");
if(isset($_POST['phonenumber']))
{
$phone = $_POST['phonenumber'];
echo "phone-->".$phone."<br />";
echo "_SESSION[phone]-->".$_SESSION['phone']."<br />";
echo "SESSIONid--->".session_id();
if($_SESSION['phone'] == $phone)
echo "POST 驗證 OK";
else
echo "POST 驗證 BAD";
}
if(isset($_GET['phonenumber']))
{
$phone = $_GET['phonenumber'];
echo "phone-->".$phone."<br />";
echo "_SESSION[phone]-->".$_SESSION['phone']."<br />";
echo "session_id--->".session_id();
if($_SESSION['phone'] == $phone)
echo "GET 驗證 OK";
else
echo "GET 驗證 BAD";
}
複製程式碼
Android上的程式碼(這裡我們分別new兩個HttpClient做測試):
複製程式碼
class myThread extends Thread {
@Override
public void run() {
try {
client = new DefaultHttpClient();
String path = "http://192.168.1.4/zxx/test.php";
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000"));
httpPost.setEntity(new UrlEncodedFormEntity(param, "utf-8"));
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
seesionId = SysOut;
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}finally
{
}
super.run();
}
}
class myThread2 extends Thread {
@Override
public void run() {
try {
client = new DefaultHttpClient();
String path = "http://192.168.1.4/zxx/test1.php?id="+seesionId;
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000"));
httpPost.setEntity(new UrlEncodedFormEntity(param, "utf-8"));
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}
super.run();
}
}
複製程式碼
Session_id($_GET['id']); 這句話很重要。
相關文章
- Android中Java與web通訊AndroidJavaWeb
- React Native與Android通訊互動React NativeAndroid
- 同一Tomcat下不同Web應用之間共享Session會話TomcatWebSession會話
- 同一會話中的多個 WebRequest會話Web
- C#通過webRequest保持在同一Session中Post資料C#WebSession
- Android 整合 Flutter 及通訊互動詳解AndroidFlutter
- Session會話Session會話
- 網路通訊3:TCP互動通訊TCP
- 在同一個Activity下實現兩個Fragment之間的通訊Fragment
- 如何基於 Agora Android SDK 在應用中實現視訊通話?GoAndroid
- Oracle 會話(Session)Oracle會話Session
- 令牌Token和會話Session原理與攻略會話Session
- MQTT 持久會話與 Clean Session 詳解MQQT會話Session
- Session會話與Cookie簡單說明Session會話Cookie
- android 視訊通話相關Android
- TensorFlow學習之會話Sesstion()和互動會話InterativeSesstion()會話
- Java Web(三) 會話機制,Cookie和Session詳解JavaWeb會話CookieSession
- Cassandra的Session會話Session會話
- 對話腦屋科技王強:《互動派對》 的核心是互動,遊戲直播的機會在互動屬性的延展遊戲
- Android 與前端互動Android前端
- 在對話中理解蘇大強們:語音互動的未來會是老齡化+個性化嗎?
- Android 8.0 中如何實現視訊通話的畫中畫模式Android模式
- 應用與互動,智慧電話的幾個重要模組
- paramiko建立可互動的ssh會話會話
- 融雲漫話:通訊中臺
- 會話技術之 Session會話Session
- Session會話管理(PHP,Apacha)Session會話PHP
- oracle session(會話) 跟蹤OracleSession會話
- 【會話】Oracle kill session系列會話OracleSession
- 會話等待(Session Waits)會話SessionAI
- 【會話】V$SESSION檢視會話Session
- 會話層技術-session會話Session
- 10、flask-會話-sessionFlask會話Session
- 在多個檔案中import同一個檔案,webpack會多次打包嗎ImportWeb
- (譯)通過WebChannel/WebSockets與QML中的HTML互動WebHTML
- 在 Flutter 多人視訊通話中實現虛擬背景、美顏與空間音效Flutter
- WEB開發中的cookie與sessionWebCookieSession
- Android中Service的啟動方式及Activity與Service的通訊方式Android