HttpClient之HttpContext使用
Multiple request sequences that represent a logically related session should be executed with the same HttpContext instance to ensure automatic propagation of conversation context and state information between requests.
上面这段话摘自httpclient官网,大体意思是逻辑会话相关的多个请求序列应该使用同一个HttpContext实例,这样就可以让会话信息和状态信息在多个请求之间自动广播。
官网上还给出一段示例代码 ,我们仿着它的示例代码,重新整一个,以便于观察。
(1) 使用springboot快迅搭建一个目标服务
@RestController
public class RequestController {
@PostMapping("/request")
public void request(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
//1. 从session中获取username
String username = (String) session.getAttribute("username");
String ret;
if (username == null) {
// 2. 从请求参数中获取username的值
username = request.getParameter("username");
session.setAttribute("username", username);
ret = "login success!";
} else {
ret = "Having been logined " + username;
}
// 将ret 内容写回到response响应体中
ServletOutputStream outputStream = null;
PrintWriter pw = null; try {
outputStream = response.getOutputStream();
pw = new PrintWriter(outputStream);
pw.write(ret); } catch (IOException e) {
e.printStackTrace();
} finally {
if (pw != null) {
pw.close();
}
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
启功类省略,server.port = 9999
(2) HttpClient测试类
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.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; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; public class HttpContextTest {
public static void main(String[] args) throws IOException { HttpContext httpContext = new BasicHttpContext();
HttpClientContext httpClientContext = HttpClientContext.adapt(httpContext); CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://localhost:9999/request");
// 模仿form表单请求,设置请求参数
List<NameValuePair> nvp = new ArrayList<>();
nvp.add(new BasicNameValuePair("username", "admin"));
// 第一次请求时,设置请求参数
httpPost.setEntity(new UrlEncodedFormEntity(nvp)); CloseableHttpResponse response = null;
try {
response = httpclient.execute(httpPost, httpClientContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
String ret = EntityUtils.toString(entity);
System.out.println("第一次请求响应:"+ ret);
}
}finally {
response.close();
} System.out.println("=================第二次请求====================");
// 重新创建一个HttpPost对象,但是此次该对象中不设置请求参数
httpPost = new HttpPost("http://localhost:9999/request");
try {
response = httpclient.execute(httpPost, httpClientContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
String ret = EntityUtils.toString(entity);
System.out.println("第二次请求响应:"+ ret);
}
}finally {
response.close();
}
}
}
(3)启动目标项目,然后再运行测试代码,打印结果如下
第一次请求响应:login success!
=================第二次请求====================
第二次请求响应:Having been logined admin Process finished with exit code 0
感觉浏览器请求一模一样了, 保存了请求会话信息,事实上确实如此,此处就是保存jsessionid
(4) 简单看下源码
<1> ProtocolExec#execute()

<2> ResponseProcessCookies#process(final HttpResponse response, final HttpContext context)
@Override
public void process(final HttpResponse response, final HttpContext context)
throws HttpException, IOException { final HttpClientContext clientContext = HttpClientContext.adapt(context); // Obtain actual CookieSpec instance
final CookieSpec cookieSpec = clientContext.getCookieSpec();
// Obtain cookie store
final CookieStore cookieStore = clientContext.getCookieStore(); //.......
// see if the cookie spec supports cookie versioning.
if (cookieSpec.getVersion() > 0) {
// process set-cookie2 headers.
// Cookie2 will replace equivalent Cookie instances
// 就是将cookie信息拷到cookieStore中
it = response.headerIterator(SM.SET_COOKIE2);
processCookies(it, cookieSpec, cookieOrigin, cookieStore);
}
}


<3> 断点查看第二次请求时HttpContext对象

通过debug可以很明显看到,HttpContext将诸多的Http请求的会话信息进行了广播。
HttpClient之HttpContext使用的更多相关文章
- 使用RestTemplate Spring安全认证
使用RestTemplate Spring安全认证 java spring 认证authentication 安全spring-security 我有提供2个独立的一整套服务2 Spring的web应 ...
- android下asynchttp库对于session的支持
默认asynchttp库不支持session,需要用户配置下cookie来处理,直接贴支持session的代码 package example.com.sessiontest; import andr ...
- .NET Http请求
声明:本代码只是我使用的网络请求方式的封装,大家如果有其他的可以一起讨论讨论. 本代码可以在.NET 与.NET CORE的平台下无须做任何改动(除非手动加一些必要的引用,resharper会有 ...
- c# API接受图片文件以文件格式上传图片
/// 文件图片上传 /// </summary> /// <returns>成功上传返回上传后的文件名</returns> [HttpPost] public a ...
- .net webapi 接收保存图片到服务器,并居中剪裁压缩图片
原文链接:https:////www.cnblogs.com/Jackyye/p/12510943.html 每天解决一些c#小问题,在写微信小程序,或者一些手机软件接口,我们经常要用到上传图片到服务 ...
- Web APi之HttpClient注意事项以及建议(四)
前言 之前对于用SelfHost来手动实现Web API的宿主模式,似乎不是太深入,所以本篇文章我们一起来讨论关于利用HttpClient来访问Web API上的资源来进行探讨以及注意相关事项,希望此 ...
- HttpClient 4.3 使用
httpclient的api变化很快,本篇随笔记录自己使用4.3.6版本时所做的设置.版本虽然不是最新,但达到了目的就行. maven依赖: <dependency> <groupI ...
- HttpClient接口测试之会话保持
HttpClient接口测试之会话保持 HttpClient4.X自带会话保持功能,使用同一个HttpClient未关闭的连接即可保持登陆会话,如果多个HttpClient想要使用一个登陆会话 ...
- HttpClient 教程 (A)
前言 超文本传输协议(HTTP)也许是当今互联网上使用的最重要的协议了.Web服务,有网络功能的设备和网络计算的发展,都持续扩展了HTTP协议的角色,超越了用户使用的Web浏览器范畴,同时,也增加了需 ...
随机推荐
- 【SQL SERVER】常见问题
[账户] 偷懒默认安装了全部默认功能到虚拟服务器上,所以并没有设置sa账户的过程,自然只能从windows身份验证进入数据库.于是还得自己来为sa账户添加登陆权限. 步骤如下: 1. windows身 ...
- java sftp.exec无法执行mv命令
编写java程序过程中,sftp上传下载建目录删除文件都可以,就是备份不行. 分析原因如下: 1.如果用的同一个用户,即sftp用户来通过 exec(ssh连接) 执行mv命令,那极有可能是在搭建sf ...
- php 的定界符 <<<eof 的问题
PHP是一个Web编程语言,在编程过程中难免会遇到用echo来输出大段的html和javascript脚本的情况,如果用传统的输出方法 ——按字符串输出的话,肯定要有大量的转义符来对字符串中的引号等特 ...
- 学习:多项式算法----FFT
FFT,即快速傅里叶变换,是离散傅里叶变换的快速方法,可以在很低复杂度内解决多项式乘积的问题(两个序列的卷积) 卷积 卷积通俗来说就一个公式(本人觉得卷积不重要) $$C_k=\sum_{i+j=k} ...
- python中函数的嵌套和作用域链
1.三元运算if条件成立的结果 if 条件 else 条件不成立的结果例如: a=20 b=10 c=a if a>b else b print(c) 2.命名空间 全局命名空间:创建的存储“变 ...
- win10下装win7双系统安装教程
win10下装win7双系统安装教程 来源:www.laomaotao.org 时间:2017-02-13 10:15 新买的电脑预装了win10系统,但win10对于有些游戏兼容性不是很好,总是会出 ...
- spring cloud gateway获取response body
网关发起请求后,微服务返回的response的值要经过网关才发给客户端.本文主要讲解在spring cloud gateway 的过滤器中获取微服务的返回值,因为很多情况我们需要对这个返回进行处理.网 ...
- Struts2之校验
##1.输入校验 错误提示页面 <%@ page language="java" contentType="text/html; charset=UTF-8&quo ...
- exports、module.exports和export、export default到底是咋回事
地址1:https://segmentfault.com/a/1190000010426778 地址2:https://blog.csdn.net/caixiaowang/article/detail ...
- java_第一年_JDBC(2)
上篇说到,通过JDBC可实现java编程程序和mysql数据库进行连接并交互,而交互后所形成的结果集是通过ResultSet对象来操作的. 创建ResultSet对象: stmt = conn.cre ...