Retrofit2.0 and OkHttp3 perfectly synchronize persistent cookies for login-free implementation tutorial (2), retrofit2.0okhttp3

Source: Internet
Author: User
Tags addall website server

Retrofit2.0 and OkHttp3 perfectly synchronize persistent cookies for login-free implementation tutorial (2), retrofit2.0okhttp3
Cookie

Cookies are a technology that allows the website server to store a small amount of data to the client's hard disk or memory, or to read data from the client's hard disk. Cookies are a very small text file placed on your hard disk by the Web server when you browse a website, it can record your user ID, password, browsed webpage, stay time, and other information. When you come to this website again, the website can read Cookies and learn your related information to make corresponding actions, such as displaying your welcome slogans on the page, or you can log on directly without entering the ID or password.

Essentially, it can be viewed as your ID card. However, Cookies cannot be executed as code, nor are viruses transmitted. They are private to you and can only be read by servers that provide them. The saved information fragments are stored in the form of "name/value" pairs (name-value pairs). A "name/value" pair is only a piece of named data. A website can only obtain information stored on your computer. It cannot obtain information from other Cookies, or get anything else on your computer.

Most of the content in Cookies is encrypted. Therefore, generally, users only seem to have meaningless combinations of letters and numbers. Only CGI processors on the server can understand their true meanings.

Cookie is also an http session tracking technology, and also contains sessions on the web side. Cookie is used to solve the stateless defects of HTTP.

Cookie Structure

Sending rule:

The browser (device) determines whether to send a Cookie based on the following rules:

Whether the requested host name matches the Domain attribute of a stored Cookie; whether the requested Port number is in the Port attribute list of the Cookie; whether the requested resource Path is in the directory and subdirectory specified by the Path attribute of the Cookie;

Whether the Cookie has expired.

The following is an example of cookie code:

 HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT(content of page)

Each Cookie in the Cookie request header field is separated by commas (,) or semicolons.

In addition to setting "name = value", the Cookie request header field can contain attribute names such as Version, Path, Domain, and Port, you must add a "$" character as the prefix.

The Version attribute can only appear once and must be located at the top of the Cookie request header field setting value. If you need to set the paths, domains, ports, and other attributes of the Cookie information, they must be placed after the "name = value" setting of the Cookie information.

The Path property points to the subdirectory Cookie before the Path property points to the parent directory Cookie.

Function Cookie in Servlet Program

The Servlet API provides a javax. servlet. http. Cookie class to disable Cookie information. It contains methods for generating Cookie information and extracting Cookie information attributes.

Cookie method:

(Constructor: public Cookie (java. lang. string name, java. lang. string value) getName method setValue and getValue Methods setMaxAge and getMaxAge Methods setPath and getPath Methods setDomian and getPath Methods setVersion and getVersion Methods setComment and getComment Methods setSecoure and getSecure Methods custom cookies

Everyone in HttpClient knows how to add cookies.

AsyncHttpClient client = new AsyncHttpClient();PersistentCookieStore myCookieStore = new PersistentCookieStore(MainActivity.this);client.setCookieStore(myCookieStore);

Therefore, you must implement a PersistentCookieStore to store OkHttpCookies in fit.

Solution 1:-PersistentCookieStore
/*** Created by LIUYONGKUI on 2016-06-09. */public class PersistentCookieStore {private static final String LOG_TAG = "PersistentCookieStore"; private static final String COOKIE_PREFS = "Cookies_Prefs"; private final Map
 
  
> Cookies; private final SharedPreferences cookiePrefs; public PersistentCookieStore (Context context) {cookiePrefs = context. getSharedPreferences (COOKIE_PREFS, 0); cookies = new HashMap <> (); // cache persistent cookies into memory, that is, map cookies Map
  
   
PrefsMap = cookiePrefs. getAll (); for (Map. Entry
   
    
Entry: prefsMap. entrySet () {String [] cookieNames = TextUtils. split (String) entry. getValue (), ","); for (String name: cookieNames) {String encodedCookie = cookiePrefs. getString (name, null); if (encodedCookie! = Null) {Cookie decodedCookie = decodeCookie (encodedCookie); if (decodedCookie! = Null) {if (! Cookies. containsKey (entry. getKey () {cookies. put (entry. getKey (), new ConcurrentHashMap
    
     
();} Cookies. get (entry. getKey ()). put (name, decodedCookie) ;}}} protected String getCookieToken (Cookie cookie) {return cookie. name () + "@" + cookie. domain ();} public void add (HttpUrl url, Cookie) {String name = getCookieToken (cookie ); // cache cookies into the memory. if the cache expires, reset the cookie if (! Cookie. persistent () {if (! Cookies. containsKey (url. host () {cookies. put (url. host (), new ConcurrentHashMap
     
      
();} Cookies. get (url. host ()). put (name, cookie);} else {if (cookies. containsKey (url. host () {cookies. get (url. host ()). remove (name) ;}// persists cookies to the local SharedPreferences. editor prefsWriter = cookiePrefs. edit (); prefsWriter. putString (url. host (), TextUtils. join (",", cookies. get (url. host ()). keySet (); prefsWriter. putString (name, encodeCookie (new OkHttpCookies (cookies); prefsWriter. apply ();} public List
      
        Get (HttpUrl url) {ArrayList
       
         Ret = new ArrayList <> (); if (cookies. containsKey (url. host () ret. addAll (cookies. get (url. host ()). values (); return ret;} public boolean removeAll () {SharedPreferences. editor prefsWriter = cookiePrefs. edit (); prefsWriter. clear (); prefsWriter. apply (); cookies. clear (); return true;} public boolean remove (HttpUrl url, Cookie) {String name = getCookieToken (cookie); if (cookies. containsKey (url. host () & cookies. get (url. host ()). containsKey (name) {cookies. get (url. host ()). remove (name); SharedPreferences. editor prefsWriter = cookiePrefs. edit (); if (cookiePrefs. contains (name) {prefsWriter. remove (name);} prefsWriter. putString (url. host (), TextUtils. join (",", cookies. get (url. host ()). keySet (); prefsWriter. apply (); return true;} else {return false;} public List
        
          GetCookies () {ArrayList
         
           Ret = new ArrayList <> (); for (String key: cookies. keySet () ret. addAll (cookies. get (key ). values (); return ret ;} /*** serialize cookies to string ** @ param cookie the cookie to be serialized * @ return the serialized string */protected String encodeCookie (okhttpcookie cookie) {if (cookie = null) return null; ByteArrayOutputStream OS = new ByteArrayOutputStream (); try {ObjectOutputStream outputStream = new ObjectOutputStream (OS); outputStream. writeObject (cookie);} catch (IOException e) {Log. d (LOG_TAG, "IOException in encodeCookie", e); return null;} return byteArrayToHexString (OS. toByteArray ();}/*** deserialize the string into cookies ** @ param cookieString cookies String * @ return cookie object */protected Cookie decodeCookie (string cookieString) {byte [] bytes = bytes (cookieString); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream (bytes); Cookie cookie = null; try {ObjectInputStream objectInputStream = new ObjectInputStream (bytes ); cookie = (OkHttpCookies) objectInputStream. readObject ()). getCookies ();} catch (IOException e) {Log. d (LOG_TAG, "IOException in decodeCookie", e);} catch (ClassNotFoundException e) {Log. d (LOG_TAG, "ClassNotFoundException in decodeCookie", e);} return cookie ;} /*** convert a binary array to a hexadecimal string ** @ param bytes byte array to be converted * @ return String containing hex values */protected string byteArrayToHexString (byte [] bytes) {StringBuilder sb = new StringBuilder (bytes. length * 2); for (byte element: bytes) {int v = element & 0xff; if (v <16) {sb. append ('0');} sb. append (Integer. toHexString (v);} return sb. toString (). toUpperCase (Locale. US );} /*** convert a hexadecimal string to a binary array ** @ param hexString String of hex-encoded values * @ return decoded byte array */protected byte [] hexStringToByteArray (string hexString) {int len = hexString. length (); byte [] data = new byte [len/2]; for (int I = 0; I <len; I + = 2) {data [I/2] = (byte) (Character. digit (hexString. charAt (I), 16) <4) + Character. digit (hexString. charAt (I + 1), 16);} return data ;}
         
        
       
      
     
    
   
  
 

The OkHttpCookies to be serialized are used to persist OkHttpCookies.

   /** * Created by LIUYONGKUI on 2016-05-20.  */public class OkHttpCookies implements Serializable {private transient final Cookie cookies;private transient Cookie clientCookies;public OkHttpCookies(Cookie cookies) {    this.cookies = cookies;}public Cookie getCookies() {    Cookie bestCookies = cookies;    if (clientCookies != null) {        bestCookies = clientCookies;    }    return bestCookies;}private void writeObject(ObjectOutputStream out) throws IOException {    out.writeObject(cookies.name());    out.writeObject(cookies.value());    out.writeLong(cookies.expiresAt());    out.writeObject(cookies.domain());    out.writeObject(cookies.path());    out.writeBoolean(cookies.secure());    out.writeBoolean(cookies.httpOnly());    out.writeBoolean(cookies.hostOnly());    out.writeBoolean(cookies.persistent());}private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {    String name = (String) in.readObject();    String value = (String) in.readObject();    long expiresAt = in.readLong();    String domain = (String) in.readObject();    String path = (String) in.readObject();    boolean secure = in.readBoolean();    boolean httpOnly = in.readBoolean();    boolean hostOnly = in.readBoolean();    boolean persistent = in.readBoolean();    Cookie.Builder builder = new Cookie.Builder();    builder = builder.name(name);    builder = builder.value(value);    builder = builder.expiresAt(expiresAt);    builder = hostOnly ? builder.hostOnlyDomain(domain) : builder.domain(domain);    builder = builder.path(path);    builder = secure ? builder.secure() : builder;    builder = httpOnly ? builder.httpOnly() : builder;    clientCookies =builder.build();}

}

-Custom CookieManger

Implement a custom CookieManger to manage cookies, implement to get set, getCookier in K-V Structure

public class CookieManger implements CookieJar {private static Context mContext;private static PersistentCookieStore cookieStore;public CookieManger(Context context) {    mContext = context;    if (cookieStore == null ) {        cookieStore = new PersistentCookieStore(mContext);    }}@Overridepublic void saveFromResponse(HttpUrl url, List
 
   cookies) {    if (cookies != null && cookies.size() > 0) {        for (Cookie item : cookies) {            cookieStore.add(url, item);        }    }}@Overridepublic List
  
    loadForRequest(HttpUrl url) {    List
   
     cookies =cookieStore.get(url);    return cookies;}}
   
  
 
-Added duplicate fit to cookie
OkHttpClient okHttpClient = new OkHttpClient.Builder()            .addNetworkInterceptor(                    new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.HEADERS))            .cookieJar(new CookieManger(context))            .addInterceptor(loginInterceptor)            .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)            .build();    Retrofit retrofit = new Retrofit.Builder()            .client(okHttpClient)            .build();
Summary

Implement persistent addition of cookies to achieve basic login-free steps

1. Implement serializable OkHttpcookies
2. Implement PersistentCookieStore for storing OkHttpcookies
3. Implement cookie management tool CookieManger
4. Build an OKHttpClient
5. Added Retrofit to the custom okHttpClient.
6. directly call the movie fitclient

Solution 2:

Method 1 may be incompatible with some websites. It can be implemented using the IT blocker.

Used to add cookies

public class ReadCookiesInterceptor implements   Interceptor { @Override  public Response intercept(Chain chain) throws IOException {    Request.Builder builder = chain.request().newBuilder();      HashSet
 
   preferences = (HashSet) Preferences.getDefaultPreferences().getStringSet(Preferences.PREF_COOKIES, new HashSet<>());     for (String cookie : preferences) {        builder.addHeader("Cookie", cookie);        Log.v("OkHttp", "Adding Header: " + cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp     }    return chain.proceed(builder.build()); }
  

}

Used to save Cookies

public class SaveCookiesInterceptor implements Interceptor {   @Override   public Response intercept(Chain chain) throws IOException {      Response originalResponse = chain.proceed(chain.request());      if (!originalResponse.headers("Set-Cookie").isEmpty()) {         HashSet
 
   cookies = new HashSet<>();         for (String header : originalResponse.headers("Set-Cookie")) {          cookies.add(header);         }         Preferences.getDefaultPreferences().edit()                .putStringSet(Preferences.PREF_COOKIES, cookies)                .apply();    }      return originalResponse;}
 

}

Okhttp
OkHttpClient okHttpClient = new OkHttpClient();okHttpClient.interceptors().add(new ReadCookiesInterceptor());okHttpClient.interceptors().add(new SaveCookiesInterceptor());
Retrofit
 Retrofit retrofit = new Retrofit.Builder()            .client(okHttpClient)            .build();
Solution 3: RxJava + Retrofit

Implement the Interceptor of OKhttp to append the local cookie to the http request header.

Public class AddCookiesInterceptor implements Interceptor {private Context context; private String lang; public AddCookiesInterceptor (Context context, String lang) {super (); this. context = context; this. lang = lang ;}@ Override public Response intercept (Chain chain) throws IOException {if (chain = null) Log. d ("http", "Addchain = null"); final Request. builder builder = chain. request (). newBuilder (); SharedPreferences sharedPreferences = context. getSharedPreferences ("cookie", Context. MODE_PRIVATE); Observable. just (sharedPreferences. getString ("cookie ","")). subscribe (new Action1
 
  
() {@ Override public void call (String cookie) {if (cookie. contains ("lang = ch") {cookie = cookie. replace ("lang = ch", "lang =" + lang);} if (cookie. contains ("lang = en") {cookie = cookie. replace ("lang = en", "lang =" + lang);} // Add cookie // Log. d ("http", "AddCookiesInterceptor" + cookie); builder. addHeader ("cookie", cookie) ;}}); return chain. proceed (builder. build ());}}
 

Implement Interceptor to store the cookie returned by Http to a local device

public class ReceivedCookiesInterceptor implements Interceptor {    private Context context;    SharedPreferences sharedPreferences;    public ReceivedCookiesInterceptor(Context context) {        super();        this.context = context;        sharedPreferences = context.getSharedPreferences("cookie", Context.MODE_PRIVATE);    }    @Override    public Response intercept(Chain chain) throws IOException {        if (chain == null)            Log.d("http", "Receivedchain == null");        Response originalResponse = chain.proceed(chain.request());        Log.d("http", "originalResponse" + originalResponse.toString());        if (!originalResponse.headers("set-cookie").isEmpty()) {            final StringBuffer cookieBuffer = new StringBuffer();            Observable.from(originalResponse.headers("set-cookie"))                    .map(new Func1
 
  () {                        @Override                        public String call(String s) {                            String[] cookieArray = s.split(";");                            return cookieArray[0];                        }                    })                    .subscribe(new Action1
  
   () {                        @Override                        public void call(String cookie) {                            cookieBuffer.append(cookie).append(";");                        }                    });            SharedPreferences.Editor editor = sharedPreferences.edit();            editor.putString("cookie", cookieBuffer.toString());            Log.d("http", "ReceivedCookiesInterceptor" + cookieBuffer.toString());            editor.commit();        }        return originalResponse;    }}
  
 

Add the Interceptor to fit. See method 2.
This method is provided by androidformjm to thank the author;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.