httpclient之httpcontext使用(代码片段)

z-qinfeng z-qinfeng     2023-05-07     550

关键词:

  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 查看详情