python requests java_java 实现类似于python requests包的Session类,自动管理cookie。

以前想用java来写接口自动化测试,总感觉没有python requests模块方便,网上找到一篇可以实现类似于requests的Session类的方法,如下:

1、在py中requests.post()和get()函数都是在那个函数内部里面自动生成了一个Session类的实例,所以requests,post和get函数要想干登陆后才能干的事情,需要添加cookie或者把cookie写在headers里面,要想自动管理cookie,就不能每次请求都实例化一个新的Session类的对象了,需要直接实例化Session类,然后使用该实例,而不是使用那两个函数。

py的Session类的使用方法是:

ss = requests.Session()

ss.post(login_url,data = {"username":"xiaomin", "password":"123456"})

ss.get(some_url)

2、java的OkHttp3默认是不自动管理cookie。

dbd4b41c38a0d087e4d32561125a7cd9.png

默认是使用NIO_COOKIES

5bbb1798cf1e02a12db789f306fc5af3.png

3、实现cookie自动管理,需要在OkhttpClient类的Builder类中的cookieJar方法传入CookieJar实例。

aa5218a8c04c1505acfa088fc4e295f0.png

实现CookieJar接口中的saveFromResponse 和loadForRequest方法,把cookie保存到haspmap中,读取也是从hashmap中,这样就实现自动管理cookie。如果要保持代码重启还能持久化cookie管理可以使用redis  sqllite 或者实现Serializable,序列化cookie到文件。

okhttp3.internal.http.BridgeInterceptor;

okhttp3.internal.http.HttpHeaders;

为什么实现了CookieJar这两个文件中会调用传进去的实例的这两个方法,根据了请求的url的域名,把cookie添加到request的header了,返回时候从header里面保存cookie,如果传的实例如果没有这两个方法那会运行出错。

d5fc76a2c738465201fc1ff1ac2f374d.png

a63666d16d4115564641366b460a89bf.png

package com.touna.httprequest;

import java.text.MessageFormat;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Set;

import java.util.regex.*;

import okhttp3.Cookie;

import okhttp3.CookieJar;

import okhttp3.FormBody;

import okhttp3.HttpUrl;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

import com.touna.view.LogUtil;

public class Session {

private final OkHttpClient mOkHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJarManager()).build();

//如果直接写个类,里面写saveFromResponse和loadForRequest,而不实现CookieJar接口,运行可以正常通过,但ide会显红,因为Bulider类的cookieJsr方法需要接受CookieJar类型的实例。鸭子类除了能节约代码行数,在可理解性 可读性 多人合作性上面都不如接口规范,谁知道鸭子类里面要写什么方法,除了写代码得人自己。

private class CookieJarManager implements CookieJar{

private final HashMap> cookieStore = new HashMap<>();

@Override

public void saveFromResponse(HttpUrl url, List cookies) {

cookieStore.put(url.host(), cookies);

}

@Override

public List loadForRequest(HttpUrl url) {

List cookies = cookieStore.get(url.host());

return cookies != null ? cookies : new ArrayList(){};

}

}

/**

* @param url 要请求的url

* @param paramsMap post的请求参数

* @return post的返回结果

*/

public String post(String url, HashMap paramsMap){

LogUtil.printLog("请求的url是:" + url);

FormBody.Builder formBodyBuilder = new FormBody.Builder();

Set keySet = paramsMap.keySet();

for(String key:keySet) {

String value = paramsMap.get(key);

formBodyBuilder.add(key,value);

}

FormBody formBody = formBodyBuilder.build();

Request request = new Request

.Builder()

.post(formBody)

.url(url)

.build();

try (Response response = mOkHttpClient.newCall(request).execute()) {

String respStr = response.body().string();

LogUtil.printLog("返回是: " + respStr);

return respStr;

}catch (Exception e){

LogUtil.printLog("post失败");

e.printStackTrace();

return "";

}

}

public String get(String url) {

final Request.Builder builder = new Request.Builder();

builder.url(url);

final Request request = builder.build();

try (Response response = mOkHttpClient.newCall(request).execute()) {

return response.body().string();

}catch (Exception e){

e.printStackTrace();

return "";

}

}

/**

* @param mail163Account 163邮箱账号;

* @param passwd 邮箱密码

* */

private static void test163(String mail163Account, String passwd){

String loginUrl = MessageFormat.format("https://mail.163.com/entry/cgi/ntesdoor?funcid=loginone&language=-1&passtype=1" +

"&iframe=1&product=mail163&from=web&df=email163&race=-2_262_-2_hz&module=&uid={0}&style=-1&net=t&skinid=null",mail163Account);

Session ss = new Session();

HashMap paramsMap = new HashMap<>() ;

paramsMap.put("username",mail163Account);

paramsMap.put("url2","http://email.163.com/errorpage/error163.htm");

paramsMap.put("savalogin","0");

paramsMap.put("password",passwd);

String respStr = ss.post(loginUrl,paramsMap); //登录

Pattern sidPattern = Pattern.compile("sid=(.*)&");

Matcher m = sidPattern.matcher(respStr);

if (!m.find()){

LogUtil.printLog("登录失败");

}else{

String sid = m.group(1);

LogUtil.printLog(sid);

String mailListUrl = MessageFormat.format("https://mail.163.com/js6/s?sid={0}&func=mbox:listMessages",sid);

HashMap dataMap = new HashMap<>() ;

dataMap.put("var","<?xml version=\"1.0\"?>1datetrue" +

"200false

"=\"topFlag\">top

truetrue");

LogUtil.printLog("读取邮件列表:");

ss.post(mailListUrl,dataMap);

}

}

public static void main(String[] args) {

test163("13148804506@163.com", "123456");

}

}

4、使用163邮箱登录,然后测试下获取邮件列表能否获取到。

测试结果,这样只要Session类的实例请求了登录接口后,就能干其他的事情了。

e07e7f572be547eae097c0f490c2fea8.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值