关键词:
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之入门使用
...应用程序来说,JDK库本身提供的功能还不够丰富和灵活。HttpClient是ApacheJakartaCommon 查看详情
小5聊asp.netcore2.1基础之开启httpcontext内容请求(代码片段)
...用新的方式1、创建一个自定义助手类 代码publicstaticclassHttpContextprivatestaticMicrosoft.AspNetCore.Http.IHttpCon 查看详情
javaspring之resttemplate的使用
...使用HTTP客户端,主要有四种:JDK原生的URLConnection、Apache的HttpClient、Netty的异步HTTPClient,Spring的RestTemplate。 解放了原先HttpClient的复杂提交,java中调用RESTful服务很典型的是使用HttpClient,对于常用的REST操作,这些方法属于... 查看详情
为我的应用程序需要与之通信的每个主机使用一个 HttpClient 实例是不是可以?
】为我的应用程序需要与之通信的每个主机使用一个HttpClient实例是不是可以?【英文标题】:IsitfinetouseoneHttpClientinstanceforeachhostmyapplicationneedstotalkto?为我的应用程序需要与之通信的每个主机使用一个HttpClient实例是否可以?【发... 查看详情
原缓存之httpruntime.cache(代码片段)
...ystem.Web命名空间下了。但是非Web应用也是可以拿来用的。HttpContext.Cache是对上述缓存类的封装,由于封装到了HttpContext,局限于只能在知道HttpContext下使用,即只能用于Web应用。2、.绝对过期时间和相对过期时间 ///<s 查看详情
轻松把玩httpclient之封装httpclient工具类,携带cookie的请求(代码片段)
...一下HttpClientUtil工具类代码,主要是添加了一个参数HttpContext,这个是用来干嘛的呢?其实是用来保存和传递Cookie所需要的。因为我们有很多时候都需要登录,然后才能请求一些想要的数据。而在这以前使用HttpClien... 查看详情
httpclient之基本使用(代码片段)
...;<groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.5<... 查看详情
http基础与android之(安卓与服务器通信)——使用httpclient和httpurlconnection
...数据的三种方式2使用HTTP协议访问网络3HttpCient简单来说用HttpClient发送请求接收响应都很简单只需要五大步骤即可要牢记4DefaultHttpClientGET方式POST 查看详情
优雅编码之——传统项目中,使用openfeign替换掉项目中的httpclient(代码片段)
使用springcloud时,当遇到服务与其他服务调用的场景,一般都会使用springcloudopenfeign来进行调用。通过@feign注解让代码变得非常简单而又优雅,即便是跨服务的调用,写起来就像项目内部自己调自己的方法一样... 查看详情
优雅编码之——传统项目中,使用openfeign替换掉项目中的httpclient(代码片段)
使用springcloud时,当遇到服务与其他服务调用的场景,一般都会使用springcloudopenfeign来进行调用。通过@feign注解让代码变得非常简单而又优雅,即便是跨服务的调用,写起来就像项目内部自己调自己的方法一样... 查看详情
httpclient
最近写了些接口,使用到了HttpClient,这里留作复习 HttpClient有新旧之分org.apache.commons.httpclient.HttpClient和org.apache.http.client.HttpClient org.apache.http.client.HttpClient取代了org.apache.commons.httpclient.HttpClient 查看详情
使用依赖注入管理多个 HttpClient 实例
】使用依赖注入管理多个HttpClient实例【英文标题】:ManagingmultipleinstancesofHttpClientusingDependencyInjection【发布时间】:2016-11-2013:27:54【问题描述】:我正在为我的Web应用程序与之通信的每个不同API创建一个HttpClient实例。我想使用Sim... 查看详情
轻松把玩httpclient之封装httpclient工具类,插件式配置header(代码片段)
上篇文章介绍了插件式配置HttpClient,本文将介绍插件式配置Header。 为什么要配置header在前面已经提到了,还里再简单说一下,要使用HttpClient模拟请求,去访问各种接口或者网站资源,都有可能有... 查看详情
使用 IAuthenticationFilter 时 HttpContext.Current 为空
】使用IAuthenticationFilter时HttpContext.Current为空【英文标题】:HttpContext.CurrentisnullwhenusingIAuthenticationFilter【发布时间】:2019-03-2515:50:26【问题描述】:我正在使用ng-file-upload上传文件,并且在使用IAuthenticationFilter时遇到了一些异常... 查看详情
Android HttpClient Cookie
...。阅读下面的帖子,您似乎在调用执行时必须传递相同的HttpContext。response=httpClient.execute(httpPost,localContext);具体做法在这篇文章中:Andr 查看详情
使用 httpcontext 打开附件
】使用httpcontext打开附件【英文标题】:openinganattachmentwithhttpcontext【发布时间】:2012-05-0716:49:09【问题描述】:我有一个附件,其数据(varbinary类型)和MIME类型来自数据库。当用户单击链接时,我获取数据并将其写入HttpContext.Re... 查看详情
什么时候应该使用 HttpContext.User.Identity.IsAuthenticated 和 SignInManager.IsSignedIn(HttpContext.User)?
】什么时候应该使用HttpContext.User.Identity.IsAuthenticated和SignInManager.IsSignedIn(HttpContext.User)?【英文标题】:WhenshouldHttpContext.User.Identity.IsAuthenticatedandSignInManager.IsSignedIn(HttpContext.User)beused?【发布时间】:2016-12-2 查看详情
httpcomponents之httpclient
HttpComponents源码目录:http://www.boyunjian.com/javasrc/org.apache.httpcomponents/httpclient/4.3.4/_/packagecom.bbkj.utils;importcom.alibaba.fastjson.JSON;importorg.apache.http.HttpEntity;importorg.apache 查看详情