Работа с HTTP-запросами#

Для отправки HTTP-запроса и обработки полученного ответа предусмотрен класс Btk_HttpPkg.

Доступна настройка конфигурации запроса RequestConfig, создание запроса HttpRequest с необходимым методом, заполнение тела запроса, обработка полученного овтета HttpResult.

Конфигурация и отправка запроса, обработка ответа#

Построение запроса#

Пример Get-запроса:

Btk_HttpPkg().get("https://httpbin.org/status/200".ns)
  .configAppend(_.setConnectTimeout(10000))
  .configAppend(_.setMaxRedirects(3))
  .headers(("key".ns, "value".ns))
  .basicAuth("login".ns, "password".ns)
  .build()
  .process(response => {
    print(response.getStatusLine.getStatusCode)
    EntityUtils.consume(response.getEntity)
  })
  .get
  • get(), post() и прочие — создание запроса с нужным методом

  • configAppend() — задаёт свойства конфигурации запроса

  • headers() — для установки заголовков

  • basicAuth() или bearerAuth() — для установки данных аутентификации

  • build() — переход к обработчикам результата

Установка тела запроса. Отправка и получение JSON#

Для Post-запроса есть возможность установки тела запроса с нужным типом содержимого с помощью методов:

  • setEntity(entity: HttpEntity)

  • setStringEntity(body: NString)

  • setJSONEntity(body: NString)

  • setXMLEntity(body: NString)

Пример запроса, передающего и получающего JSON-объект:

val svRequestBody = """{ "data": "Some Data Sample" }"""
val jvResponseBody = Btk_HttpPkg().post("https://httpbin.org/anything".ns)
  .setJSONEntity(svRequestBody)
  .build()
  .getJObject()
  .get
print(jvResponseBody)

Обработка результата#

Метод process#

  • С помощью лямбды HttpResponse -> T

  • Реализовав интерфейс org.apache.http.client.ResponseHandler

  • Реализовав интерфейс org.apache.http.impl.client.AbstractResponseHandler (Автоматическое формирование ошибок при http статусе >= 300)

Внимание

При обработке ответа с помощью пользовательского ResponseHandler, необходимо освобождать ресурсы и соединение, связанные с ответом.

  1. Ручным закрытием response.getEntity.getContent.close()

  2. Передачей response.getEntity.getContent в методы которые сами закрывают InputStream

  3. Вызовом EntityUtils.consume(response.getEntity)

Готовые обработчики#

Также, помимо process(), к использованию доступны следующие методы для получения ответа:

  • execute() — выполнить запрос и вернуть Try[Unit]

  • getText() — тело ответа в виде строки. Try[NString]

  • getJObject() — ответ в виде Try[JObject]

  • getJArray() — ответ в виде Try[JArray]

  • forStream[T](f: InputStream => T) — обработать InputStream, полученный из содержимого ответа

Обработка ошибок#

Пример обработки ответа с ошибкой:

try app {
  val jvResponseBody = Btk_HttpPkg().post("https://httpbin.org/json".ns)
    .basicAuth("login".ns, "password".ns)
    .setStringEntity("data")
    .build()
    .getJObject() match {
      // HttpResponseException если были использованы готовые обработчики или основанный на `HttpResponseException`.
      case Failure(ex: HttpResponseException) if ex.getStatusCode == 401 =>
        throw AppException(s"Ошибка ответа на запрос. Код: ${ex.getStatusCode}. Причина: Неверный логин или пароль.")
      case Failure(ex: HttpResponseException) if ex.getStatusCode == 405 =>
        throw AppException(s"Ошибка ответа на запрос. Код: ${ex.getStatusCode}. Причина: Использование недопустимого метода.")
      // Ошибки обработки, socket timeout и тп
      case Failure(ex) => throw ex
      case Success(jObj) => jObj
    }
  print(jvResponseBody)
}