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浏览器范畴,同时,也增加了需 ...
随机推荐
- Integer自动装箱和拆箱
Integer a=3; => Integer a=Integer.valueOf(3); /** *@description: 自动装箱和拆箱 *@auther: yangsj *@ ...
- 测开之路八十一:参数定义之*args和**kwargs
# *,不定长参数,*args# 定义函数参数def avg(score, *scores): return (score + sum(scores)) / (len(scores) + 1) ...
- Jenkins+Gitlab+自动化测试配置持续集成
Jenkins安装在win7上 GitLab安装在docker上 需求:本地提交自动化测试代码在gitlab上后,jenkins自动构建,拉下新提交的自动化代码,并且运行 参考的链接: https:/ ...
- Installing Symfony project with PHP 7.3 version
参考地址:https://cmsdk.com/php/installing-symfony-project-with-php-7-3-version.html Tryng to install (an ...
- CodeIgniter 技巧 - 通过 Composer 安装 CodeIgniter 框架并安装依赖包
PHP 项目中,通过 Composer 来管理各种依赖包,类似 Java 中的 Maven,或 Node 中的 npm.CodeIgniter 框架要想通过 Composer 自动加载包也很简单,步骤 ...
- Python笔记(十九)_继承
继承 继承可以把父类的所有功能都直接拿过来,这样就不必从零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写 多重继承 通过多重继承,一个子类就可以同时获得多个父类的所有功能 > ...
- 【ABAP系列】SAP ABAP基础-数据更新至数据库操作解析
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP基础-数据更新至 ...
- Java thread(2)
这一块主要是从Thread类源码的角度来分析两种线程的实现方式,这里分析的也仅仅是最基本的部分. 就从线程的启动函数 start方法开始分析 只是分析最主要的部分 在start()方法中,除了grou ...
- Web控件中Eval()的使用
1.使用Eval()绑定数据时使用三元运算符 <%#Eval("hg_A").ToString()=="1"?"通过":Eval(&q ...
- P2747 [USACO5.4]周游加拿大Canada Tour
题目描述 你赢得了一场航空公司举办的比赛,奖品是一张加拿大环游机票.旅行在这家航空公司开放的最西边的城市开始,然后一直自西向东旅行,直到你到达最东边的城市,再由东向西返回,直到你回到开始的城市.除了旅 ...