首先是一個Servlet用於本次試驗。html
package com.lu.controller; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @SuppressWarnings("serial") public class RirectServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=utf-8"); OutputStream out = response.getOutputStream(); PrintWriter pw = new PrintWriter(out); // 記錄返回的內容 String returnContent = null; HttpSession session = request.getSession(); String user = (String) session.getAttribute("username"); // 若是不爲空,說明已登陸 if (user != null) { returnContent = "you have been logined, " + user; } else { // 爲空說明未登陸,設置username到session中 String username = request.getParameter("username"); session.setAttribute("username", username); returnContent = "login success"; } try { pw.println(returnContent); } finally { pw.close(); out.close(); } } }
在本機中訪問URI爲:http://localhost:8080/spiderweb/RirectServletjava
下面看請求web
package com.lu.test; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; public class HttpClientTest { private static HttpContext localContext = new BasicHttpContext(); private static HttpClientContext context = HttpClientContext .adapt(localContext); public static void main(String[] args) throws Exception { CloseableHttpClient httpClient = HttpClients.createDefault(); try { // 模擬表單 List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("username", "**")); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8"); HttpPost httpPost = new HttpPost( "http://localhost:8080/spiderweb/RirectServlet"); httpPost.setEntity(entity); // 將HttpClientContext傳入execute()中 CloseableHttpResponse response = httpClient.execute(httpPost, context); try { HttpEntity responseEntity = response.getEntity(); System.out.println(EntityUtils.toString(responseEntity)); } finally { response.close(); } } finally { httpClient.close(); } CloseableHttpClient httpClient2 = HttpClients.createDefault(); try { HttpGet httpGet = new HttpGet( "http://localhost:8080/spiderweb/RirectServlet"); // 設置相同的HttpClientContext CloseableHttpResponse response = httpClient2.execute(httpGet, context); try { HttpEntity entity = response.getEntity(); System.out.println(EntityUtils.toString(entity)); } finally { response.close(); } } finally { httpClient2.close(); } } }
輸出結果爲:apache
login success
you have been logined, **瀏覽器
可能你們認爲這個結果很正常。第一次登錄了,第二次確定會輸出you have been logined, **。可是你們別忘了,如今不是在瀏覽器環境下,瀏覽器會幫你提取服務器傳回的sessionId並在你下次請求的時候傳給服務器,那麼兩次請求用的就是同一個session對象,那麼天然的就會有上面的輸出。服務器
可是如今是在本身寫代碼訪問。咱們沒有獲取sessionId,也沒有向服務器傳送sessionId,那麼兩次請求服務器就會爲你建立兩個sessionId不一樣的session對象。cookie
那爲何輸出結果倒是跟瀏覽器獲得的結果同樣呢?確定是什麼東西爲咱們自動完成了獲取sessionId傳送sessionId的功能。毫無疑問,就是context。 BasicHttpContext裏有個Map<Object,Object>的對象用來記錄一次請求響應的信息,當響應信息返回時,就會被set到context裏,固然響應的cookie信息也就被存儲在context裏,包括傳回的sessionId。session
當第二次請求的時候傳入相同的context,那麼請求的過程當中會將context裏的sessionId提取出來傳給服務器,sessionId同樣,天然而然的就是同一個session對象。
那麼你們明白context的做用了嗎?
按照官方教程的說法來講ide
表明一個邏輯相關的會話的多個請求序列應該具備相同的HttpContext實例以確保請求之間的信息狀態的自動傳播this
因爲初學,不對的地方還望你們指出。