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类的实例请求了登录接口后,就能干其他的事情了。

java 实现类似于python requests包的Session类,自动管理cookie。的更多相关文章

  1. 【转载】JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案

    JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案 本文为转载,原文地址为:https://www.cnblogs.com/adversary/p/103 ...

  2. 关于python requests 包跑ssl的设置 和 charles相关抓包的问题

    由于在测试服务器上测试东西都是https,然后最近又在和大神一起开发openapi,api写好当然是要测试的 python上测试接口最好用的莫过于requests模块了.但是 我还从来没有用reque ...

  3. 关于python requests包新版本设置代理的问题

    在更新了requests包之后,发现我电脑上的charles工具无法再成功抓取到数据包.百度了半年都没有找到原因. 然后 我使用了 google 查到了 charles的最新的文档发现.需要设置代理, ...

  4. [Python] iupdatable包:Timer 类使用介绍

    iudatable包是我对常用函数进行的封装后发布的一个python包,教程汇总目录: [Python] iupdatable包使用说明 安装 iupdatable 包 pip install iup ...

  5. python requests包的基本使用

    Requests 安装requests模块: D:\Install\Python36>pip3 install requests 请求方式 #coding:utf-8 import reques ...

  6. python requests.request 和session.request区别究竟在哪里

    import requests hd={"X-auth":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzeXN0ZW0iLCJBUEkiOiIvdW ...

  7. python requests 包 使用

    1: 发送带 cookie 的 请求 resp = requests.get(self.url_item_list_first_page, cookies=self.cookies) >> ...

  8. Java 控制台执行带自定义包定义的类,出现“Exception in thread "main" java.lang.NoClassDefFoundError: ConnectSQLServer (wrong name: sine/ConnectSQLServer)”

    1.先说明一下代码实现:自定义package sine, 源代码保存路径为:E:\JSP\HibernateDemo\HibernateDemoProject\src\sine\ConnectSQLS ...

  9. java如何调用另一个包里面的类

    我现在有两个包: 我想在Boss里面实现对Employee的调用, Employee.java: package payroll2; public class Employee { public vo ...

随机推荐

  1. 搭建自己的挂Q平台

    准备工作: 在前篇[分享]免费建立自己的站点里面介绍了怎么申请免费域名和空间. 在这里[随记]Q号解除限制一波三折有我被挂Q工具坑苦的经历. 在网上(出处不明了,下载的包太多,非CSDN)下载到的免费 ...

  2. .NET中使用FastReport实现打印功能

    FastReport是功能非常强大的报表工具,在本篇文章中讲解如何使用FastReport实现打印功能. 一.新建一个窗体程序,窗体上面有设计界面和预览界面两个按钮,分别对应FastReport的设计 ...

  3. WampServer 常见问题

    Wamp就是Windows 下的Apache Mysql PHP集成环境. 支持phpmyadmin 注意:安装前请先安装VC 2010运行库(vcredist2010.exe ),否则会提示没有找到 ...

  4. PHP数组缓存:三种方式JSON、序列化和var_export的比较

    使用PHP的站点系统,在面对大数据量的时候不得不引入缓存机制.有一种简单有效的办法是将PHP的对象缓存到文件里.下面我来对这3种缓存方法进行说明和比较. 第一种方法:JSONJSON缓存变量的方式主要 ...

  5. C# 最全的系统帮助类

    using System;using System.Collections;using System.Collections.Generic;using System.Configuration;us ...

  6. Android studio导入framework编译的classes.jar包

    1.在libs文件夹中加入jar包,并将其置顶 注:studio3.1的scope没有Provided选项,都默认选择implementation,studio2.3及以下版本需要将scope设置为P ...

  7. r table

    一.table 函数对应的就是统计学中的列联表,是一种记录频数的方法,对于统计来说有非常重要的应用,下面的例子都是针对维数为2的情况举例,多维的情况是类似的 下面看一个例子: > ct < ...

  8. 【转】Smartphone--Android真机管理平台

    背景 最近在工作中发现几个问题: 作为测试人员,在做产品兼容性测试时,发现手上的测试设备总是不够用,但是可能其他同事的设备在闲置着: 作为Android和H5开发人员,如果测试同事发现一个兼容性的bu ...

  9. 访问网站出现EOF

    HTTP/0.0 503 Service Unavailable Date: Tuesday, 18-Apr-17 10:29:46 CST Keep-Alive: timeout=38 EOF 今天 ...

  10. iOS开发OC基础:Xcode中常见英文总结,OC常见英文错误

    在开发的过程中难免会遇到很多的错误,可是当看到系统给出的英文时,又不知道是什么意思.所以这篇文章总结了Xcode中常见的一些英文单词及词组,可以帮助初学的人快速了解给出的提示.多练习,就肯定能基本掌握 ...