我正在尝试从此URL https://fantasy.premierleague.com/drf/elements解析JSON,但我从okhttp和Postman得到的响应却不同。 我还使用了在线API测试器,并且在那里也收到了完整的JSON的响应。 我不确定为什么我的代码无法正常工作。

谁能帮我解决这个问题?

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

    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的代码段标头,这些标头是:

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();

但可惜那里也没有运气。

日志:

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 = 

如您所见,主体为空,“连接”为关闭。

这是Postman得到的响应头,有很大的不同。

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

如您所见,“连接”表示保持活动。

我的Request.Builder()中缺少什么才能使其正常工作吗?

编辑:

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

            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, .... }]

#1楼 票数:2 已采纳

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

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() }
}

  ask by MikeOscarEcho translate from so

未解决问题?本站智能推荐:

3回复

OkHttp3 拦截器向请求正文添加字段

由于我的 API 请求都包含一些共同的 json 字段,我想在拦截器中添加这些字段,但我正在努力修改拦截器中的 OkHttp3 RequestBody 这是我的改造建造者: 这是拦截器: 例如,如何将 "traceId" : "abc123" 添加到拦截器内的所有请求正文中?
1回复

Dynamsoft Android SDK与okhttp3冲突

我正在一个公司项目中工作,因此需要集成Dynamsoft Android SDK进行文档扫描。 问题是,当将sdk依赖项添加到当前项目时,它在构建控制台上出现此错误的同时与okhttp3冲突: **任务':app:transformDexArchiveWithExternalLibsDe
1回复

从邮递员在OKHTTP上获得不同的结果

我正在尝试从服务器获取一些数据。 主要问题是我没有服务器访问权限,但是我当然知道请求的详细信息,我使用PostMan测试服务器调用,而不是使用OkHttp在android上实现它们。 这是我使用HttpUrlConnection或OkHttp从android端的服务器获取的信息:
1回复

从Postman生成的代码在Android项目中无法正常工作

我有用Python编写的API服务,并在Postman中提供了有关它的文档。 Postman中的所有请求都工作正常,但是从文件上传请求返回“内部服务器错误”生成的Java代码(带有OkHttp库),我检查了服务器日志,发现该文件未传送,在进入views.py之前崩溃了。 向邮递员索取屏幕
1回复

Okhttp3,retrofit2 POST上的FileNotFoundException

当我显示下面代码的一部分时,我正在尝试使用retrofit2发布图像。 Android Studio 我真的不明白这是什么错误,希望有人帮助我解决这个问题。 图像服务 图像请求和改造init 活动代码 当我尝试发布此图像文件时,出现此错误 如您在错误
1回复

将拦截器添加到已构建的okHttp3客户端中

是否可以将拦截器添加到已构建的okHttp3客户端中? 我使用单例客户端,并希望将Interceptor添加到已构建的客户端中,因此我可以向客户端添加自定义cookie,而不必手动将其添加到每个请求中。 直接从客户端访问拦截器列表将返回一个不可变列表。
1回复

使用Android体系结构定期获取更新的OkHttp响应:LiveData和更新Map标记

我已经制作了显示公交车位置的运输应用程序。 我目前正在尝试重构代码,以便可以平滑地对标记(总线位置)进行动画处理,并且看到LiveData可以用于清理代码。 我使用OkHttp发出请求,使用存储库返回BusInfo类型的mutableList,然后从busInfo的可变列表中创建标记。 我
1回复

使用Retrofit + OkHttp + Gson,api通过邮递员返回json返回html

我在邮递员中测试了我的api,它返回了json 只是一个简单的获取api baseurl / ecom-services / api / mobile / tasks / user / tokenhere_ / upcoming 但是在Android上 这将返回一个ht