Okhttp3 请求返回空响应以及与 Postman 不同的标头 [英] Okhttp3 request returning empty response as well as different headers than Postman

查看:123
本文介绍了Okhttp3 请求返回空响应以及与 Postman 不同的标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从这个 URL 解析 JSON,https://fantasy.premierleague.com/drf/elements 但我从 okhttp 和 Postman 得到的响应是不同的.我还使用了在线 API 测试人员,我也得到了完整 JSON 的响应.我不知道为什么我的代码不起作用.

I'm trying to parse the JSON from this URL, https://fantasy.premierleague.com/drf/elements but the response I get from okhttp and Postman are different. I've also used online API testers and I get a response back with the full JSON there as well. I'm not sure why my code isn't working.

谁能帮我解决这个问题?

Can anyone help me figure this out?

这是我用于快速测试的代码.

Here's the code I'm using for quick testing.

    val request = Request.Builder()
            .url("https://fantasy.premierleague.com/drf/elements")
            .get()
            .addHeader("accept", "*/*")
            .addHeader("accept-encoding", "gzip, deflate")
            .addHeader("cache-control", "no-cache")
            .addHeader("connection", "keep-alive")
            .cacheControl(CacheControl.FORCE_NETWORK)
            .build()

    val httpClient = OkHttpClient()
    httpClient.newCall(request).enqueue(object : okhttp3.Callback {
        override fun onFailure(call: okhttp3.Call?, e: IOException?) {
            Timber.d("FPL response failed = " + e?.message.toString())
        }

        override fun onResponse(call: okhttp3.Call?, response: okhttp3.Response?) {
            if (response!!.isSuccessful) {

                val responseBody = response.body()?.string()
                try {
                    val obj = JSONObject(responseBody)
                    Timber.d("FPL response = " + obj.toString())
                } catch (t: Throwable) {
                    Timber.e("Could not parse malformed JSON: " + t.message)
                }

                Timber.d("FPL response = $response")
                Timber.d("FPL headers = " + response.headers())
                Timber.d("FPL body = " + responseBody)
            } else {
                Timber.d("FPL response failed = " + response.body().toString())
            }
        }
    })

我尝试复制 Postman 的代码片段标题,它们是:

I tried replicating Postman's code snippet headers which are:

Request request = new Request.Builder()
  .url("https://fantasy.premierleague.com/drf/elements")
  .get()
  .addHeader("cache-control", "no-cache")
  .addHeader("postman-token", "05ae03ef-cf44-618c-a82c-5762e245b771")
  .build();

但遗憾的是那里也没有运气.

but sadly no luck there either.

日志:

D/HomeController$onAttach:L135: FPL response = Response{protocol=http/1.1, code=200, message=OK, url=https://fantasy.premierleague.com/drf/elements}

D/HomeController$onAttach:L138: FPL headers = 
Server: Varnish
Retry-After: 0
Content-Type: application/json
Content-Length: 0
Accept-Ranges: bytes
Date: Tue, 15 Aug 2017 22:17:18 GMT
Via: 1.1 varnish
Connection: close
X-Served-By: cache-jfk8123-JFK
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1502835438.419014,VS0,VE0

D/HomeController$onAttach:L139: FPL body = 

如您所见,正文为空,连接"已关闭.

As you can see, the body is empty and "Connection" is close.

这是 Postman 得到的响应头,非常不同.

Here's the response headers that Postman gets, much different.

Accept-Ranges →bytes
Age →14
Allow →GET, HEAD, OPTIONS
Cache-Control →no-cache, no-store, must-revalidate, max-age=0
Connection →keep-alive
Content-Encoding →gzip
Content-Language →plfplen
Content-Length →39518
Content-Type →application/json
Date →Tue, 15 Aug 2017 00:54:32 GMT
Edge-Control →max-age=60
Fastly-Debug-Digest →fdb44d2dd7c0b26c639a8b3476f8c63661c68707cc3b9446f8ed3941cd3fe01e
Server →nginx
Vary →Accept-Encoding
Via →1.1 varnish
Via →1.1 varnish
X-Cache →HIT, MISS
X-Cache-Hits →1, 0
X-Frame-Options →DENY
X-Served-By →cache-lcy1146-LCY, cache-jfk8143-JFK
X-Timer →S1502758472.116470,VS0,VE82

如您所见,连接"表示保持活动状态.

as you can see, "Connection" says keep alive.

我的 Request.Builder() 中是否缺少某些东西才能使其正常工作?

Is there something I'm missing in my Request.Builder() to get this to work?

因此,我决定尝试使用 AsyncTask 发出请求,并获得完整的 JSON,如您在下面的日志中所见.我不明白为什么 Okhttp3 不起作用.

So, I decided to try making the request using an AsyncTask, and got the full JSON back as you can see in the log under. I don't understand why Okhttp3 isn't working.

            val url = params[0]
            var stream: InputStream? = null
            var connection: HttpsURLConnection? = null
            var result: String? = null
            try {
                connection = url?.openConnection() as HttpsURLConnection?
                // Timeout for reading InputStream arbitrarily set to 3000ms.
                connection?.readTimeout = 3000
                // Timeout for connection.connect() arbitrarily set to 3000ms.
                connection?.connectTimeout = 3000
                // For this use case, set HTTP method to GET.
                connection?.requestMethod = "GET"
                // Already true by default but setting just in case; needs to be true since this request
                // is carrying an input (response) body.
                connection?.doInput = true
                // Open communications link (network traffic occurs here).
                connection?.connect()

                val responseCode = connection?.responseCode

                if (responseCode != HttpsURLConnection.HTTP_OK) {
                    throw IOException("HTTP error code: " + responseCode)
                }
                // Retrieve the response body as an InputStream.
                stream = connection?.inputStream

                Timber.d("httpurl stream = " + connection?.inputStream.toString())

                if (stream != null) {
                    // Converts Stream to String with max length of 500.
                result = readStream(stream, 500)
                }
            } finally {
                // Close Stream and disconnect HTTPS connection.
                if (stream != null) {
                    stream.close()
                }
                if (connection != null) {
                    connection.disconnect()
                }
            }

            return result

日志:

 D/HomeController$NetworkA:L266: httpurl response = [{"id":1,"photo":"48844.jpg","web_name":"Ospina","team_code":3,"status":"a","code":48844,"first_name":"David","second_name":"Ospina","squad_number":13,"news":"","now_cost":50, .... }]

推荐答案

您的问题是 User-Agent 标题.这是一个工作示例:

Your problem is User-Agent header. Here is a working example:

fun syncGetOkHttp() {
    println("\n===")
    println("OkHttp")
    println("===")
    val client = OkHttpClient().newBuilder()
            .addNetworkInterceptor { chain ->
                val (request, response) = chain.request().let {
                    Pair(it, chain.proceed(it))
                }

                println("--> ${RequestLine.get(request, Proxy.Type.HTTP)})")
                println("Headers: (${request.headers().size()})")
                request.headers().toMultimap().forEach { k, v -> println("$k : $v") }

                println("<-- ${response.code()} (${request.url()})")

                val body = if (response.body() != null)
                    GZIPInputStream(response.body()!!.byteStream()).use {
                        it.readBytes(50000)
                    } else null

                println("Response: ${StatusLine.get(response)}")
                println("Length: (${body?.size ?: 0})")

                println("""Body: ${if (body != null && body.isNotEmpty()) String(body) else "(empty)"}""")
                println("Headers: (${response.headers().size()})")
                response.headers().toMultimap().forEach { k, v -> println("$k : $v") }

                response
            }
            .build()

    Request.Builder()
            .url(url)
            .header("Accept", "application/json")
            .header("User-Agent", "Mozilla/5.0")
            .build()
            .let { client.newCall(it).execute() }
}

这篇关于Okhttp3 请求返回空响应以及与 Postman 不同的标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆