解决Android4.4及以下Volley框架Patch请求报错问题(Kotlin)

来源:互联网 发布:淘宝授权书怎么写 编辑:程序博客网 时间:2024/05/18 19:39

volley请求在4.4以下调用patch请求,会报以下错误

java.net.ProtocolException: Unknown methodPATCH’; must be one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE]

解决方案:
借助okHttp发送请求

1.导入相关jar包:
okhttp-2.2.0.jar
okhttp-urlconnection-2.2.0.jar
okio-1.2.0.jar
httpcore-4.2.4
下载地址:okhttp相关包

2.新建OkHttpStack类(Kotlin代码)

import com.android.volley.toolbox.HttpStackimport com.android.volley.AuthFailureErrorimport com.android.volley.Requestimport com.squareup.okhttp.MediaTypeimport com.squareup.okhttp.OkHttpClientimport com.squareup.okhttp.Protocolimport com.squareup.okhttp.RequestBodyimport org.apache.http.HttpEntityimport org.apache.http.ProtocolVersionimport org.apache.http.entity.BasicHttpEntityimport org.apache.http.message.BasicHeaderimport org.apache.http.message.BasicHttpResponseimport org.apache.http.message.BasicStatusLineimport java.io.IOExceptionimport java.util.concurrent.TimeUnit/** * Created by Raleigh.Luo on 17/11/20. * 解决Volley Patch请求在5.0以下不能使用的问题 * com.android.volley.NoConnectionError: java.net.ProtocolException: Unknown method 'PATCH'; must be one of [OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE] */class OkHttpStack : HttpStack {    private val mClient: OkHttpClient    constructor(client: OkHttpClient) {        this.mClient = client    }    @Throws(IOException::class, AuthFailureError::class)    override fun performRequest(request: Request<*>?, additionalHeaders: MutableMap<String, String>?): org.apache.http.HttpResponse {        val client = mClient.clone()        val timeoutMs = request?.getTimeoutMs()?.toLong()?:0L        client.setConnectTimeout(timeoutMs, TimeUnit.MILLISECONDS)        client.setReadTimeout(timeoutMs, TimeUnit.MILLISECONDS)        client.setWriteTimeout(timeoutMs, TimeUnit.MILLISECONDS)        val okHttpRequestBuilder = com.squareup.okhttp.Request.Builder()        okHttpRequestBuilder.url(request?.getUrl())        val headers = request?.getHeaders()        headers?.keys?.let {            for (name in it) {                okHttpRequestBuilder.addHeader(name, headers.get(name))            }        }        additionalHeaders?.keys?.let {            for (name in it) {                okHttpRequestBuilder.addHeader(name, additionalHeaders[name])            }        }        setConnectionParametersForRequest(okHttpRequestBuilder, request!!)        val okHttpRequest = okHttpRequestBuilder.build()        val okHttpCall = client.newCall(okHttpRequest)        val okHttpResponse = okHttpCall.execute()        val responseStatus = BasicStatusLine(                parseProtocol(okHttpResponse.protocol()),                okHttpResponse.code(),                okHttpResponse.message()        )        val response = BasicHttpResponse(responseStatus)        response.setEntity(entityFromOkHttpResponse(okHttpResponse))        val responseHeaders = okHttpResponse.headers()        var i = 0        val len = responseHeaders.size()        while (i < len) {            val name = responseHeaders.name(i)            val value = responseHeaders.value(i)            if (name != null) {                response.addHeader(BasicHeader(name, value))            }            i++        }        return response    }    @Throws(IOException::class)    private fun entityFromOkHttpResponse(r: com.squareup.okhttp.Response): HttpEntity {        val entity = BasicHttpEntity()        val body = r.body()        entity.content = body.byteStream()        entity.contentLength = body.contentLength()        entity.setContentEncoding(r.header("Content-Encoding"))        if (body.contentType() != null) {            entity.setContentType(body.contentType().type())        }        return entity    }    @Throws(IOException::class, AuthFailureError::class)    private fun setConnectionParametersForRequest(builder: com.squareup.okhttp.Request.Builder, request: Request<*>) {        when (request.getMethod()) {            Request.Method.DEPRECATED_GET_OR_POST -> {                // Ensure backwards compatibility.                // Volley assumes a request with a null body is a GET.                val postBody = request.getPostBody()                if (postBody != null) {                    builder.post(RequestBody.create(MediaType.parse(request.getPostBodyContentType()), postBody))                }            }            Request.Method.GET -> builder.get()            Request.Method.DELETE -> builder.delete()            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("TRACE", null)            Request.Method.PATCH -> builder.patch(createRequestBody(request))            else -> throw IllegalStateException("Unknown method type.")        }    }    private fun parseProtocol(p: Protocol): ProtocolVersion {        when (p) {            Protocol.HTTP_1_0 -> return ProtocolVersion("HTTP", 1, 0)            Protocol.HTTP_1_1 -> return ProtocolVersion("HTTP", 1, 1)            Protocol.SPDY_3 -> return ProtocolVersion("SPDY", 3, 1)            Protocol.HTTP_2 -> return ProtocolVersion("HTTP", 2, 0)        }        throw IllegalAccessError("Unkwown protocol")    }    @Throws(AuthFailureError::class)    private fun createRequestBody(r: Request<*>): RequestBody? {        val body = r.body ?: return null        return RequestBody.create(MediaType.parse(r.bodyContentType), body)    }}

4.再添加到volley请求队列中

                    if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){//5.0及以上使用volley                                      Volley.newRequestQueue(getApplicationContext()).add(request)}else{//5.0以下使用okhttp                                          Volley.newRequestQueue(getApplicationContext(),new OkHttpStack()).add(request)}

request和volley中的request一致,可以使用jsonRequest,stringRequest和jsonArrayRequest

阅读全文
0 0
原创粉丝点击