Java implements the Session class similar to the python requests package, and automatically manages cookies.

1. In py, the requests.post() and get() functions automatically generate an instance of the Session class inside that function, so if the requests, post and get functions want to do things that can only be done after logging in, they need to be added cookie or write the cookie in the headers. If you want to automatically manage cookies, you can’t instantiate a new Session class object every time you request it. You need to instantiate the Session class directly and then use the instance instead of using the two function.

The usage of py’s Session class is:

ss = requests.Session()

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

ss. get(some_url)

2. Java’s OkHttp3 does not automatically manage cookies by default.

The default is to use NIO_COOKIES

3. To implement automatic cookie management, you need to pass in the CookieJar instance to the cookieJar method in the Builder class of the OkhttpClient class.

Implement the saveFromResponse and loadForRequest methods in the CookieJar interface, save the cookie in the haspmap, and read from the hashmap, so that automatic management of cookies is realized. If you want to keep the code restart and persist cookie management, you can use redis sqllite or implement Serializable to serialize cookies to files.

okhttp3.internal.http.BridgeInterceptor;<br>okhttp3.internal.http.HttpHeaders;<br>Why are the two methods of the passed-in instance called in the two files of CookieJar? According to the domain name of the requested url, the cookie is added to the header of the request, and the cookie is saved from the header when returning. If the passed instance If there are no these two methods, it will run wrong. 

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();<br>//If you directly write a class with saveFromResponse and loadForRequest in it, without implementing the CookieJar interface, the operation can pass normally, but the ide will be red, because the cookieJsr method of the Bulider class needs to accept instances of the CookieJar type. In addition to saving the number of lines of code, the duck class is not as good as the interface specification in terms of comprehensibility, readability, and multi-person cooperation. Who knows what method to write in the duck class, except for the person who writes the code.
    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 the url to request
     * @param paramsMap request parameters of post
     * @return result of post
     */
    public String post(String url, HashMap<String, String > paramsMap){
        LogUtil.printLog("The requested url is:" + 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("The return is: " + respStr);
            return respStr;
        }catch (Exception e){
            LogUtil.printLog("post failed");
            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 email account;
     * @param passwd email password
     * */
    private static void test163(String mail163Account, String passwd){
        String loginUrl = MessageFormat.format("https://mail.163.com/entry/cgi/ntesdoor?funcid=loginone & amp;language=-1 & amp;passtype=1" +
                " & amp;iframe=1 & amp;product=mail163 & amp;from=web & amp;df=email163 & amp;race=-2_262_-2_hz & amp;module= & amp;uid={0} & amp ;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); //login

        Pattern sidPattern = Pattern.compile("sid=(.*) &");
        Matcher m = sidPattern. matcher(respStr);
        if (!m.find()){
            LogUtil.printLog("login failed");
        }else{
            String sid = m. group(1);
            LogUtil. printLog(sid);
            String mailListUrl = MessageFormat.format("https://mail.163.com/js6/s?sid={0} & amp;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("Read mailing list:");
            ss. post(mailListUrl, dataMap);
        }
    }

    public static void main(String[] args) {
        test163("[email protected]", "123456");
    }

}

4. Use the 163 mailbox to log in, and then test whether you can get the mailing list.

Test results, so that as long as the instance of the Session class requests the login interface, it can do other things.