OkHttpResponse - проанализировать полученные фрагментированные данные text / html - PullRequest
0 голосов
/ 02 февраля 2020

У меня проблема с анализом фрагментированного ответа от сервера. Вот как я создаю запрос (имитирующий отправку формы) с постом.

val requestBody = MultipartBody.Builder()
  .setType(MultipartBody.FORM)
  .addFormDataPart("key1","value1")
  .build()


val requestBuilder = Request.Builder()
  .url(formActionUrl)
  .method("POST",requestBody)
  .build()

val response = okHttpClient
                .newCall(requestBuilder)
                .execute()

Проблема для меня здесь, когда я пытаюсь прочитать основной текст.

 if(isChunked){
   val responseBody = response.body
   val source = responseBody!!.source ()
   val buffer = Buffer () 
   val builder = java.lang.StringBuilder()
   while (!source.exhausted ()) {
      val readBytes = source.read (buffer, Long.MAX_VALUE)
      val data = buffer.readString (Charset.forName ("UTF-8"))
      builder.append(data)
   }
   Log.d("builder",builder.toString())
}

Это регистрация некоторых символов. И я не могу получить данные HTML.

Отладка: Я попытался повторить точный вызов с почтальоном, но я успешно получаю ответ HTML при отладке со Stetho я не вижу ответа HTML (вкладка ответа пуста), хотя я получаю 200 успешных кодов.

Полагаю, мне придется каким-то образом читать фрагменты, возможно, пользовательский перехватчик или что-то в этом роде. Кто-нибудь может дать мне подсказку о том, как разобрать / прочитать источник из ответа? - Спасибо!

1 Ответ

0 голосов
/ 09 февраля 2020

через некоторое время я разобрался сам. По сути, мне нужно было прочитать фрагменты из исходного кода и проанализировать их, которые были закодированы с помощью Gzip (кодировка может быть найдена в заголовках ответов - Content-Encoding ) Так что в основном это код:

   val isChunked = isChunked(response.headers)
   val subtype = responseBody.contentType()!!.subtype.toLowerCase() //html
   val type = responseBody.contentType()!!.type.toLowerCase() //text
   val charset = responseBody.contentType()!!.charset().toString()//UTF-8

   val buffer = Buffer()
   if(isChunked) {
      while (!source.exhausted()) {
         source.read(buffer, 8192)
      }
      source.close()
   }

   if(subtype.contains("html")) {
      val pureHtml = GZIPInputStream(buffer.inputStream())
         .bufferedReader(UTF_8)
         .use { it.readText() }
         buffer.flush()
      webview.loadData(pureHtml,"$type/$subtype",charset)
   }else{
      //handle diff types
   }

Имейте в виду, что тело ответа может быть прочитано только один раз. См. Ниже в соответствии с квадратными документами:

Ответные тела должны быть закрыты и могут быть использованы только один раз

Также при чтении документов Square рекомендует закрыть ответ и тело, как потенциально может замедлить приложение.

...