zoukankan      html  css  js  c++  java
  • java 实现类似于python requests包的Session类,自动管理cookie。

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

    原文地址:https://blog.csdn.net/weixin_34117211/article/details/85979529

    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。

    默认是使用NIO_COOKIES

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

     实现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,如果传的实例如果没有这两个方法那会运行出错。

     

    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<String, List<Cookie>> cookieStore = new HashMap<>(); @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { cookieStore.put(url.host(), cookies); } @Override public List<Cookie> loadForRequest(HttpUrl url) { List<Cookie> cookies = cookieStore.get(url.host()); return cookies != null ? cookies : new ArrayList<Cookie>(){}; } } /** * @param url 要请求的url * @param paramsMap post的请求参数 * @return post的返回结果 */ public String post(String url, HashMap<String, String > paramsMap){ LogUtil.printLog("请求的url是:" + url); FormBody.Builder formBodyBuilder = new FormBody.Builder(); Set<String> 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<String,String> 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<String,String> dataMap = new HashMap<>() ; dataMap.put("var","<?xml version="1.0"?><object><int name="fid">1</int><string name="order">date</string><boolean name="desc">true" + "</boolean><int name="limit">20</int><int name="start">0</int><boolean name="skipLockedFolders">false</boolean><string name" + "="topFlag">top</string><boolean name="returnTag">true</boolean><boolean name="returnTotal">true</boolean></object>"); LogUtil.printLog("读取邮件列表:"); ss.post(mailListUrl,dataMap); } } public static void main(String[] args) { test163("13148804506@163.com", "123456"); } }

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

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

  • 相关阅读:
    Powershell数据处理
    Powershell About Active Directory Group Membership of a domain user
    Powershell About Active Directory Server
    Oracle Schema Objects——Tables——TableStorage
    Oracle Schema Objects——Tables——TableType
    English Grammar
    Oracle Database Documentation
    Oracle Schema Objects——Tables——Oracle Data Types
    Oracle Schema Objects——Tables——Overview of Tables
    What is Grammar?
  • 原文地址:https://www.cnblogs.com/linwenbin/p/11362708.html
Copyright © 2011-2022 走看看