解决Java+HttpClient+TestNg接口鉴权问题(获取Cookie)

描述

在做接口自动化时,如果接口需要从登录接口中获取Cookie,并且把Cookie带入后面的接口请求头中进行后续的接口操作。如果不带入Cookie测试接口时会出现重定向301,比如在jmeter中会有自动重定向和跟随重定向一样。

jmeter跟随重定向与自动重定向区别

自动重定向:HttpClient接收到请求后,如果请求中包含重定向请求,HttpClient是可以自动跳转的,但是只针对GET和Head请求,勾选此项则“跟随重定向”失效;自动重定向可以自动转向到最终目标页面,但是JMeter是不记录重定向过程内容的,比如在查看结果树中是无法找到重定向过程内容的(A重定向到B,此时只记录B的内容不记录A的内容,A的响应内容我们暂时且叫过程内容),如果此时你想做关联,那就比较遗憾了,你无法关联到。
跟随重定向:Http Request取样器的默认选项,但响应Code是3XX时(比如301是重定向),自动跳转至目标地址。与自动重定向不同,JMeter会记录重定向过程中的所有请求响应,在查看结果树时可以看到服务器返回的内容,所以你可以对响应的内容做关联
比如你要测试登录,你把POST请求改为跟随重定向就可以了

案例

有两个接口,分别是登录接口和添加接口,添加接口需要从登录接口中获取Cookie并且放入请求头中才能请求成功。

使用框架Java+HttpClient+TestNg

public class Demo {
//保存获取的Cookie值
    public Map<String, String> cookie = new HashMap<String, String>();

    @Test
    public void test_1() {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost("接口地址");
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("username", "测试专员"));
        params.add(new BasicNameValuePair("pwd", "123456789"));
        try {
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            HttpResponse report = httpClient.execute(post);
            getAndStoreCookiesFromResponse(report);
            if (report.getStatusLine().getStatusCode()== 200) {
                String result = EntityUtils.toString(report.getEntity());
                System.out.println(result);
            } else {
                System.out.println("请求失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test(dependsOnMethods = {"test_1"})
    public void test_2() throws Exception {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost("接口地址");
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("name", "webApii"));
        params.add(new BasicNameValuePair("yn", "1"));
        params.add(new BasicNameValuePair("authScope", "3"));
        params.add(new BasicNameValuePair("type", "1"));
        params.add(new BasicNameValuePair("menuIds", "325,1011,1102,11024,11029"));
        post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
        addCookieInRequestHeaderBeforeRequest(post);
        HttpResponse report = httpClient.execute(post);
        if (report.getStatusLine().getStatusCode() == 200) {
            String result = EntityUtils.toString(report.getEntity());
            System.out.println(result);
        } else {
            System.out.println("请求失败");
        }
    }
    private void addCookieInRequestHeaderBeforeRequest(HttpPost post) {
        String pinIdCookie = cookie.get("pin");
        System.out.println(pinIdCookie);
        if (pinIdCookie != null) {
            post.setHeader("Cookie", pinIdCookie);
        }
    }
    private void getAndStoreCookiesFromResponse(HttpResponse report) {
        Header setCookieHeader = report.getFirstHeader("Set-Cookie");
        if (setCookieHeader != null) {
            String cookiePairsString = setCookieHeader.getValue();
            System.out.println("Set-Cookie:" + cookiePairsString);
            if (cookiePairsString != null && cookiePairsString.trim().length() > 0) {
                String[] cookiePairs = cookiePairsString.split(";");
                if (cookiePairs != null) {
                    for (String cookiePair : cookiePairs) {
                        if (cookiePair.contains("pin")) {
                            cookie.put("pin", cookiePair);
                        }
                    }
                }
            }
        }
    }
}

执行结果

代码执行结果

代码详解

1. 登录接口

 @Test
    public void test_1() {
    /*httpclients模拟https访问,下面示例通过HttpClients.createDefault()方式创建CloseableHttpClient对象实例(取代用new DefaultHttpClient()实例化) 解决了HTTPS安全证书认证问题。*/
        HttpClient httpClient = HttpClients.createDefault();
        //声明请求方式Post方式
        HttpPost post = new HttpPost("接口地址");
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("username", "测试专员"));
        params.add(new BasicNameValuePair("pwd", "123456789"));
        try {
        //将数据放入post请求中
            post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            //执行post请求并且返回响应体
            HttpResponse report = httpClient.execute(post);
            //从响应体中获取响应报文中的Cookie
            getAndStoreCookiesFromResponse(report);
            //获取状态码,如果状态码为200,接口请求成功,并且获取响应数据
            if (report.getStatusLine().getStatusCode()== 200) {
                String result = EntityUtils.toString(report.getEntity());
                System.out.println(result);
            } else {
                System.out.println("请求失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.保存Cookie

//保存获取的Cookie值
    public Map<String, String> cookie = new HashMap<String, String>();

3.获取Cookie的方法

  private void getAndStoreCookiesFromResponse(HttpResponse report) {
  //从响应头中取出名字为"Set-Cookie"的响应头
        Header setCookieHeader = report.getFirstHeader("Set-Cookie");
        //如果取出的"Set-Cookie"不为空,取出响应头的值
        if (setCookieHeader != null) {
            String cookiePairsString = setCookieHeader.getValue();
            System.out.println("Set-Cookie:" + cookiePairsString);
            if (cookiePairsString != null && cookiePairsString.trim().length() > 0) {
            //以";"分割
                String[] cookiePairs = cookiePairsString.split(";");
                if (cookiePairs != null) {
                    for (String cookiePair : cookiePairs) {
                        if (cookiePair.contains("pin")) {
                        //取出Cookie值保存到map集合中
                            cookie.put("pin", cookiePair);
                        }
                    }
                }
            }
        }
    }

4.添加接口

/*TestNG框架中的依赖,因为Cookie是从第一个登录接口中获取的,添加接口需要使用Cookie则需要依赖登录方法,只有登录方法执行完后获取cookie,添加方法才能获取到并且使用*/
   @Test(dependsOnMethods = {"test_1"})
    public void test_2() throws Exception {
        HttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost("接口地址");
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("name", "webApii"));
        params.add(new BasicNameValuePair("yn", "1"));
        params.add(new BasicNameValuePair("authScope", "3"));
        params.add(new BasicNameValuePair("type", "1"));
        params.add(new BasicNameValuePair("menuIds", "325,1011,1102,11024,11029"));
        post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
        //将获取到的Cookie设置到添加方法的Post请求中
        addCookieInRequestHeaderBeforeRequest(post);
        //执行Post请求
        HttpResponse report = httpClient.execute(post);
        if (report.getStatusLine().getStatusCode() == 200) {
            String result = EntityUtils.toString(report.getEntity());
            System.out.println(result);
        } else {
            System.out.println("请求失败");
        }
    }

5.添加Cookie方法

    private void addCookieInRequestHeaderBeforeRequest(HttpPost post) {
        //根据Key获取Value
        String pinIdCookie = cookie.get("pin");
        System.out.println(pinIdCookie);
        if (pinIdCookie != null) {
        //将获取的Cookie放入Header中
            post.setHeader("Cookie", pinIdCookie);
        }
    }
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值