首先是一个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
因为初学,不对的地方还望你们指出。