ITPub博客

首页 > 数据库 > 数据库开发技术 > httpclient处理多用户同时在线

httpclient处理多用户同时在线

原创 数据库开发技术 作者:FunTester 时间:2019-08-19 09:43:26 0 删除 编辑

在使用httpclient做接口相关测试的过程中,遇到过一个障碍:如何处理多用户同时登陆。之前用户身份凭证一般都是做公参里面处理或者在header中单独定义一个或者几个字段,cookie都是使用httpclient自带的管理器自动管理的。

后来用户凭证存到了cookie里,这里就有了一些障碍,经过翻看资料得到了解决。

首先取消cookie的自动管理

设置如下:

 1    /**
2     * 获取请求超时控制器
3     * <p>
4     * cookieSpec:即cookie策略。参数为cookiespecs的一些字段。作用:
5     * 1、如果网站header中有set-cookie字段时,采用默认方式可能会被cookie reject,无法写入cookie。将此属性设置成CookieSpecs.STANDARD_STRICT可避免此情况。
6     * 2、如果要想忽略cookie访问,则将此属性设置成CookieSpecs.IGNORE_COOKIES。
7     * </p>
8     *
9     * @return
10     */

11    private static RequestConfig getRequestConfig() {
12        return RequestConfig.custom().setConnectionRequestTimeout(HttpClientConstant.CONNECT_REQUEST_TIMEOUT).setConnectTimeout(HttpClientConstant.CONNECT_TIMEOUT).setSocketTimeout(HttpClientConstant.SOCKET_TIMEOUT).setCookieSpec(CookieSpecs.IGNORE_COOKIES).setRedirectsEnabled(false).build();
13    }

这里说明一点,这个requestconfig既可以在对HTTPrequestbase进行设置,也可以对CloseableHttpClient进行设置,由于在各个项目中都采取了单独处理cookie的设置,所以我是直接放在了连接池CloseableHttpClient对象的设置里面,如下:

 1    /**
2     * 通过连接池获取https协议请求对象
3     * <p>
4     * 此处会默认添加一天defaultcookiesstore,会处理响应头中的set-cookie字段
5     * 增加默认的请求控制器
6     * </p>
7     *
8     * @return
9     */

10    private static CloseableHttpClient getCloseableHttpsClients() {
11        // 创建自定义的httpsclient对象
12        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).setRetryHandler(httpRequestRetryHandler).setDefaultRequestConfig(requestConfig).build();
13//         CloseableHttpClient client = HttpClients.createDefault();//非连接池创建
14        return client;
15    }

其次处理set-cookie信息

我的方案是在处理响应的时候,只用closeablehttpresponse对象接收响应的,然后在单独在header里面遍历set-cookie字段的值,在处理json对象作为返回体的时候添加进去,如下:

 1    /**
2     * 响应结束之后,处理响应头信息,如set-cookien内容
3     *
4     * @param response 响应内容
5     * @return
6     */

7    private static JSONObject afterResponse(CloseableHttpResponse response) {
8        JSONObject cookies = new JSONObject();
9        List<Header> headers = Arrays.asList(response.getHeaders("Set-Cookie"));
10        if (headers.size() == 0) return cookies;
11        headers.forEach(x -> {
12            String[] split = x.getValue().split(";")[0].split("=", 2);
13            cookies.put(split[0], split[1]);
14        });
15        return cookies;
16    }
17
18
19    /**
20     * 根据解析好的content,转化json对象
21     *
22     * @param content
23     * @return
24     */

25    private static JSONObject getJsonResponse(String content, JSONObject cookies) {
26        JSONObject jsonObject = new JSONObject();
27        try {
28            jsonObject = JSONObject.fromObject(content);
29        } catch (Exception e) {
30            jsonObject.put("content", content);
31            jsonObject.put("code", TEST_ERROR_CODE);
32            logger.warn("响应体非json格式,已经自动转换成json格式!");
33        } finally {
34            if (!cookies.isEmpty()) jsonObject.put(HttpClientConstant.COOKIE, cookies);
35            return jsonObject;
36        }
37    }

最后处理多用户保存和携带cookie

在每个项目的base对象接收到响应之后存储cookie以便子类继承,在每次发送请求的时候带上当前对象的cookie,以对象形式存储每一个用户,达到多用户同时登录的目的,如下:

 1    @Override
2    public JSONObject getResponse(HttpRequestBase httpRequestBase) {
3        setHeaders(httpRequestBase);
4        JSONObject response = FanLibrary.getHttpResponse(httpRequestBase);
5        handleResponseHeader(response);
6        return response;
7    }
8
9    @Override
10    public void setHeaders(HttpRequestBase httpRequestBase) {
11        httpRequestBase.addHeader(Common.REQUEST_ID);
12        httpRequestBase.addHeader(FanLibrary.getHeader("token", token));
13        if (!cookies.isEmpty()) httpRequestBase.addHeader(FanLibrary.getCookies(cookies));
14    }
15
16    @Override
17    public void handleResponseHeader(JSONObject response) {
18        if (!response.containsKey(HttpClientConstant.COOKIE)) return;
19        cookies.putAll(response.getJSONObject(HttpClientConstant.COOKIE));
20        response.remove(HttpClientConstant.COOKIE);
21    }
  • 在多用户多线程请求的场景下,在初始化每一个对象的时候小概率会发生一些问题:可能同一个对象会被初始化多次,这样在第二次初始化之前创建的子类对象存储的cookie会失效,由于没有做通知改变功能(多线程编程搞不定),所以测试的时候统一采用了线程绑定用户的模式,一个线程对应一个用户,防止发生混乱。

往期文章精选

  1. java一行代码打印心形

  2. Linux性能监控软件netdata中文汉化版

  3. 接口测试代码覆盖率(jacoco)方案分享

  4. 性能测试框架

  5. 如何在Linux命令行界面愉快进行性能测试

  6. 图解HTTP脑图

  7. 写给所有人的编程思维

  8. 测试之JVM命令脑图

  9. 将json数据格式化输出到控制台

  10. 如何测试概率型业务接口

  11. “双花”BUG的测试分享

  12. 将swagger文档自动变成测试代码

公众号地图 ☢️ 一起来~FunTester

原文作者:FunTester;如有侵权,请联系管理员删除。

上一篇: 公众号地图
请登录后发表评论 登录
全部评论

注册时间:2019-07-07

  • 博文量
    1037
  • 访问量
    420672