OkHttp3 쿠키 로컬 SharedPrefrence 관리

11907 단어
interface ICookieStore {

    /**    url  cookie*/
    fun saveCookie(url: HttpUrl?, cookies: MutableList?)

    /**    url   cookie*/
    fun loadCookie(httpUrl: HttpUrl): List

    /**    cookie*/
    fun loadAllCookie(): List

    /**    cookie*/
    fun removeAllCookie(): Boolean

    /**    url cookie*/
    fun removeCookie(httpUrl: HttpUrl): Boolean
}
/**
 * Created by HeXiangyuan on 18-3-21.
 * Description:  cookie           SP opt_cookie_sp 
 *
 * sp        key :url.host   value :,opr_cookie_cookie1,opt_cookie_cookie2,opt_cookie_cookie3
 */
object CookieMgr {
    const val COOKIE_SP = "OPT_COOKIE_SP"
    private const val COOKIE_PREFIX = ",opt_cookie_"

    fun mapCookiesToString(httpUrl: HttpUrl, cookies: List): String {
        return if (cookies.isEmpty()) {
            ""
        } else {
            val sb = StringBuilder()
            cookies.forEach {
                sb.append(CookieMgr.COOKIE_PREFIX)
                sb.append(SerializableCookie.encodeCookie(httpUrl.host(), it))
            }
            sb.toString()
        }
    }

    fun mapStringToCookies(cookieString: String): MutableList {
        return if (cookieString.isEmpty()) {
            mutableListOf()
        } else {
            val cookies = arrayListOf()
            cookieString
                    .split(CookieMgr.COOKIE_PREFIX)
                    .forEach {
                        if (!it.isEmpty()) {
                            val cookie = SerializableCookie.decodeCookie(it)
                            Log.e("cookieLog", "name == ${cookie.name()}  domain == ${cookie.domain()}  cookieString == $cookie ")
                            cookies.add(cookie)
                        }
                    }
            return cookies
        }
    }

    /** Cookie name  domain       ,
     *           map  key        
     *         cookie   name  domain
     * */
    fun addToCookies(originCookies: MutableList, cookies: MutableList?): MutableList {
        if (cookies == null || cookies.size == 0) {
            return originCookies
        } else {
            val cookieMap = ConcurrentHashMap()
            originCookies.forEach {
                cookieMap.put("${it.name()}@${it.domain()}", it)
            }
            cookies.forEach {
                cookieMap.put("${it.name()}@${it.domain()}", it)
            }
            val currentCookie = mutableListOf()
            cookieMap.forEach {
                currentCookie.add(it.value)
            }
            return currentCookie
        }
    }
}

class LocalCookieStore(val context: Application) : ICookieStore {
    private val cookieSp: SharedPreferences = context.getSharedPreferences(CookieMgr.COOKIE_SP, MODE_PRIVATE)
    private val cookiesMap: ConcurrentHashMap> = ConcurrentHashMap()

    init {
        //       Cookie   Sp       
        cookieSp.all.forEach {
            if (it.value != null) {
                cookiesMap[it.key] = CookieMgr.mapStringToCookies(it.value.toString())
            }
        }
    }

    @Synchronized
    override fun saveCookie(url: HttpUrl?, cookies: MutableList?) {
        if (cookies != null && url != null) {
            //        
            val newCookie = CookieMgr.addToCookies(cookiesMap[url.host()] ?: arrayListOf(), cookies)
            cookiesMap[url.host()] = newCookie

            val prefsWriter = cookieSp.edit()
            prefsWriter.putString(url.host(), CookieMgr.mapCookiesToString(url, newCookie))
            prefsWriter.apply()
        }
    }

    override fun loadCookie(httpUrl: HttpUrl): List {
        if (cookiesMap.containsKey(httpUrl.host())) {
            return cookiesMap[httpUrl.host()] ?: emptyList()
        }
        return emptyList()
    }

    override fun loadAllCookie(): List {
        val cookies = arrayListOf()
        cookiesMap.forEach {
            it.value.forEach { cookie ->
                cookies.add(cookie)
            }
        }
        return cookies
    }

    override fun removeAllCookie(): Boolean {
        cookiesMap.clear()
        cookieSp.edit().clear().apply()
        return true
    }

    override fun removeCookie(httpUrl: HttpUrl): Boolean {
        cookiesMap.remove(httpUrl.host())
        cookieSp.edit().remove(httpUrl.host()).apply()
        return true
    }

}
class MyCookieJarImp( val cookieStore: ICookieStore) : CookieJar {

    override fun saveFromResponse(url: HttpUrl?, cookies: MutableList?) {
        cookieStore.saveCookie(url, cookies)
    }

    override fun loadForRequest(url: HttpUrl?): List {
        return if (url != null) {
            cookieStore.loadCookie(url)
        } else {
            emptyList()
        }
    }

}
public class SerializableCookie implements Serializable {
    private static final long serialVersionUID = 6374381323722046732L;

    public static final String HOST = "host";
    public static final String NAME = "name";
    public static final String DOMAIN = "domain";
    public static final String COOKIE = "cookie";

    public String host;
    public String name;
    public String domain;
    private transient Cookie cookie;
    private transient Cookie clientCookie;

    public SerializableCookie(String host, Cookie cookie) {
        this.cookie = cookie;
        this.host = host;
        this.name = cookie.name();
        this.domain = cookie.domain();
    }

    public Cookie getCookie() {
        Cookie bestCookie = cookie;
        if (clientCookie != null) {
            bestCookie = clientCookie;
        }
        return bestCookie;
    }

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeObject(cookie.name());
        out.writeObject(cookie.value());
        out.writeLong(cookie.expiresAt());
        out.writeObject(cookie.domain());
        out.writeObject(cookie.path());
        out.writeBoolean(cookie.secure());
        out.writeBoolean(cookie.httpOnly());
        out.writeBoolean(cookie.hostOnly());
        out.writeBoolean(cookie.persistent());
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        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;
        clientCookie = builder.build();
    }

    public static SerializableCookie parseCursorToBean(Cursor cursor) {
        String host = cursor.getString(cursor.getColumnIndex(HOST));
        byte[] cookieBytes = cursor.getBlob(cursor.getColumnIndex(COOKIE));
        Cookie cookie = bytesToCookie(cookieBytes);
        return new SerializableCookie(host, cookie);
    }

    public static ContentValues getContentValues(SerializableCookie serializableCookie) {
        ContentValues values = new ContentValues();
        values.put(SerializableCookie.HOST, serializableCookie.host);
        values.put(SerializableCookie.NAME, serializableCookie.name);
        values.put(SerializableCookie.DOMAIN, serializableCookie.domain);
        values.put(SerializableCookie.COOKIE, cookieToBytes(serializableCookie.host, serializableCookie.getCookie()));
        return values;
    }

    /**
     * cookies      string
     *
     * @param cookie     
     * @return       string
     */
    public static String encodeCookie(String host, Cookie cookie) {
        if (cookie == null) return null;
        byte[] cookieBytes = cookieToBytes(host, cookie);
        return byteArrayToHexString(cookieBytes);
    }

    public static byte[] cookieToBytes(String host, Cookie cookie) {
        SerializableCookie serializableCookie = new SerializableCookie(host, cookie);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ObjectOutputStream outputStream = new ObjectOutputStream(os);
            outputStream.writeObject(serializableCookie);
        } catch (IOException e) {

            return null;
        }
        return os.toByteArray();
    }

    /**
     *          cookies
     *
     * @param cookieString cookies string
     * @return cookie object
     */
    public static Cookie decodeCookie(String cookieString) {
        byte[] bytes = hexStringToByteArray(cookieString);
        return bytesToCookie(bytes);
    }

    public static Cookie bytesToCookie(byte[] bytes) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        Cookie cookie = null;
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            cookie = ((SerializableCookie) objectInputStream.readObject()).getCookie();
        } catch (Exception e) {

        }
        return cookie;
    }

    /**
     *              
     *
     * @param bytes byte array to be converted
     * @return string containing hex values
     */
    private static 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);
    }

    /**
     *              
     *
     * @param hexString string of hex-encoded values
     * @return decoded byte array
     */
    private static 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;
    }

    /** host, name, domain     cookie     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        SerializableCookie that = (SerializableCookie) o;

        if (host != null ? !host.equals(that.host) : that.host != null) return false;
        if (name != null ? !name.equals(that.name) : that.name != null) return false;
        return domain != null ? domain.equals(that.domain) : that.domain == null;
    }

    @Override
    public int hashCode() {
        int result = host != null ? host.hashCode() : 0;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (domain != null ? domain.hashCode() : 0);
        return result;
    }
}
OkHttpClient.Builder()
                    ...
                    .cookieJar(MyCookieJarImp(LocalCookieStore(context)))
.build()

좋은 웹페이지 즐겨찾기