Created
September 3, 2019 02:04
-
-
Save CodeK1988/62a0315f6541b4189e7336c48d7b643b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 旧项目中使用Volley | |
| 移植入Okhttp Retrofit 如何同步cookie | |
| 1.之前的思路: | |
| Volley 底层替换 | |
| class OkHttpStack( | |
| private val okHttpClient: OkHttpClient | |
| ) : BaseHttpStack() { | |
| @Throws(AuthFailureError::class) | |
| private fun setConnectionParametersForRequest(builder: okhttp3.Request.Builder, request: Request<*>) { | |
| when (request.method) { | |
| Request.Method.DEPRECATED_GET_OR_POST -> { | |
| // Ensure backwards compatibility. Volley assumes a request with a null body is a GET. | |
| val postBody = request.body | |
| if (postBody != null) { | |
| builder.post(RequestBody.create(MediaType.parse(request.bodyContentType), postBody)) | |
| } | |
| } | |
| Request.Method.GET -> builder.get() | |
| Request.Method.DELETE -> builder.delete(createRequestBody(request)) | |
| Request.Method.POST -> builder.post(createRequestBody(request)) | |
| Request.Method.PUT -> builder.put(createRequestBody(request)) | |
| Request.Method.HEAD -> builder.head() | |
| Request.Method.OPTIONS -> builder.method("OPTIONS", null) | |
| Request.Method.TRACE -> builder.method("TRPersistentCookieStoreACE", null) | |
| Request.Method.PATCH -> builder.patch(createRequestBody(request)) | |
| else -> throw IllegalStateException("Unknown method type.") | |
| } | |
| } | |
| @Throws(AuthFailureError::class) | |
| private fun createRequestBody(r: Request<*>): RequestBody? { | |
| val body = r.body ?: return null | |
| return RequestBody.create(MediaType.parse(r.bodyContentType), body) | |
| } | |
| @Throws(IOException::class, AuthFailureError::class) | |
| override fun executeRequest(request: Request<*>, additionalHeaders: Map<String, String>): HttpResponse { | |
| val timeoutMs = request.timeoutMs | |
| val clientBuilder = okHttpClient.newBuilder() | |
| clientBuilder.connectTimeout(timeoutMs.toLong(), TimeUnit.MILLISECONDS) | |
| clientBuilder.readTimeout(timeoutMs.toLong(), TimeUnit.MILLISECONDS) | |
| clientBuilder.writeTimeout(timeoutMs.toLong(), TimeUnit.MILLISECONDS) | |
| val okHttpRequestBuilder = okhttp3.Request.Builder() | |
| okHttpRequestBuilder.url(request.url) | |
| val headers = request.headers | |
| headers.keys.forEach { name -> | |
| headers[name]?.also { value -> | |
| okHttpRequestBuilder.addHeader(name, value) | |
| } | |
| } | |
| additionalHeaders.keys.forEach { name -> | |
| additionalHeaders[name]?.also { value -> | |
| okHttpRequestBuilder.addHeader(name, value) | |
| } | |
| } | |
| setConnectionParametersForRequest(okHttpRequestBuilder, request) | |
| val client = clientBuilder.build() | |
| val okHttpRequest = okHttpRequestBuilder.build() | |
| val okHttpCall = client.newCall(okHttpRequest) | |
| val okHttpResponse = okHttpCall.execute() | |
| val code = okHttpResponse.code() | |
| val body = okHttpResponse.body() | |
| val content = body?.byteStream() | |
| val contentLength = body?.contentLength()?.toInt() ?: 0 | |
| val responseHeaders = mapHeaders(okHttpResponse.headers()) | |
| return HttpResponse(code, responseHeaders, contentLength, content) | |
| } | |
| private fun mapHeaders(responseHeaders: Headers): List<Header> { | |
| val headers = ArrayList<Header>() | |
| (0 until responseHeaders.size()).forEach { | |
| headers.add(Header(responseHeaders.name(it), responseHeaders.value(it))) | |
| } | |
| return headers | |
| } | |
| } | |
| CookieHandler.setDefault(new CookieManager(new SPCookieStore(context), CookiePolicy.ACCEPT_ALL)); | |
| Volley.newRequestQueue(context, new OkHttpStack(getClient())); | |
| fun getClient(): OkHttpClient { | |
| val cookieJar = JavaNetCookieJar(CookieManager(PersistentCookieStore(CETApplication.mcontext), CookiePolicy.ACCEPT_ALL)) | |
| return OkHttpClient.Builder() | |
| // .cookieJar(CookieJarImpl(CookieHandler.getDefault())) | |
| .cookieJar(cookieJar) // not working first time when login in | |
| .addInterceptor(OnlineInterceptor()) | |
| .addNetworkInterceptor(OnlineInterceptor()) | |
| .addInterceptor(HttpLoggingInterceptor().apply { | |
| level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE | |
| }) | |
| .build() | |
| } | |
| not working first time when login in cookie没办法同步也可能我写的有问题。 | |
| 2.Volley用Volley的一套 只保证新引入的Okhttp cookie能同步即可 | |
| Volley.newRequestQueue(context,new CustomHurlStack()); | |
| Okhttp .setOkHttpClient(getClient()) | |
| fun getClient(): OkHttpClient { | |
| return OkHttpClient.Builder() | |
| .cookieJar(CookieJarImpl(CookieHandler.getDefault())) | |
| .addNetworkInterceptor(OnlineInterceptor()) | |
| .addInterceptor(HttpLoggingInterceptor().apply { | |
| level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE | |
| }) | |
| .build() | |
| } | |
| class CookieJarImpl(private val cookieHandler: CookieHandler?) : CookieJar { | |
| override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) { | |
| if (cookieHandler != null) { | |
| val cookieStrings = ArrayList<String>() | |
| for (cookie in cookies) { | |
| cookieStrings.add(cookie.toString().replace("; domain=".toRegex(), "; domain=.")) | |
| } | |
| val multimap = Collections.singletonMap<String, List<String>>("Set-Cookie", cookieStrings) | |
| try { | |
| cookieHandler.put(url.uri(), multimap) | |
| } catch (e: IOException) { | |
| Platform.get().log(WARN, "Saving cookies failed for " + url.resolve("/...")!!, e) | |
| } | |
| } | |
| } | |
| override fun loadForRequest(url: HttpUrl): List<Cookie> { | |
| val headers = emptyMap<String, List<String>>() | |
| val cookieHeaders: Map<String, List<String>> | |
| try { | |
| cookieHeaders = cookieHandler!!.get(url.uri(), headers) | |
| } catch (e: Exception) { | |
| return emptyList() | |
| } | |
| var cookies: MutableList<Cookie>? = null | |
| for ((key, value) in cookieHeaders) { | |
| if (("Cookie".equals(key, ignoreCase = true) || "Cookie2".equals( | |
| key, | |
| ignoreCase = true | |
| )) && !value.isEmpty() | |
| ) { | |
| for (header in value) { | |
| if (cookies == null) cookies = ArrayList() | |
| cookies.addAll(decodeHeaderAsJavaNetCookies(url, header)) | |
| } | |
| } | |
| } | |
| return if (cookies != null) | |
| Collections.unmodifiableList(cookies) | |
| else | |
| emptyList() | |
| } | |
| private fun decodeHeaderAsJavaNetCookies(url: HttpUrl, header: String): List<Cookie> { | |
| val result = ArrayList<Cookie>() | |
| var pos = 0 | |
| val limit = header.length | |
| var pairEnd: Int | |
| while (pos < limit) { | |
| pairEnd = delimiterOffset(header, pos, limit, ";,") | |
| val equalsSign = delimiterOffset(header, pos, pairEnd, '=') | |
| val name = trimSubstring(header, pos, equalsSign) | |
| if (name.startsWith("$")) { | |
| pos = pairEnd + 1 | |
| continue | |
| } | |
| val value = if (equalsSign < pairEnd) | |
| trimSubstring(header, equalsSign + 1, pairEnd) | |
| else | |
| "" | |
| result.add( | |
| Cookie.Builder() | |
| .name(name) | |
| .value(value) | |
| .domain(url.host()) | |
| .build() | |
| ) | |
| pos = pairEnd + 1 | |
| } | |
| return result | |
| } | |
| } | |
| 这样是正常工作的~ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment