Как я могу обработать 403 с XML.load в Scala? - PullRequest
1 голос
/ 27 апреля 2011

Я пишу клиент Scala для взаимодействия с Amazon RESTful Product API . Чтобы вернуть XML для данного запроса, я использую:

XML.load(uri)

Это работает нормально, за исключением того, что иногда, когда Amazon не нравится, например, Подпись встроена в uri и поэтому возвращает 403 (вместе с действительным отчетом об ошибках XML). К сожалению, это 403 создает исключение в пределах XML.load:

java.io.IOException: Server returned HTTP response code: 403 for URL: http://...

В идеале я хотел бы отметить способ исключения, но в любом случае вернуть XML-код ошибки. Есть ли простой способ сделать это с XML.load, который мне не хватает, или мне нужно будет разбить его на двухэтапный процесс get-then-load?

Ответы [ 5 ]

4 голосов
/ 27 апреля 2011

XML.load (URL) использует Java java.net.URL.openStream (), который выбрасывает IOException таким образом, что не дает никакого доступа к «Потоку ошибок»

Таким образом, вы можете сделать более длинную последовательность вызовов, чтобы получить InputStream, а затем вы можете XML.load этого результирующего InputStream.

Использовать URL.openConnection () (вместо URL.openStream),и затем вызовите HttpURLConnection.getInputStream () из блока try.Затем в вашем блоке catch вызовите HttpURLConnection.getErrorStream ().

http://download.oracle.com/javase/6/docs/api/java/net/URL.html#openConnection%28%29

http://download.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html#getErrorStream%28%29

Теперь вы можете вызывать XML.load (InputStream) для результирующегоInputStream.

Надеюсь, этого будет достаточно, чтобы отправиться в путь.

2 голосов
/ 30 апреля 2011

Это код, который я в итоге написал, большое спасибо за все указания выше. (Если что-то из приведенного ниже может быть улучшено / сделано более идиоматичным, пожалуйста, дайте мне знать):

val url = new URL("http://ecs.amazonaws...")

val connection = url.openConnection() match {
  case x: HttpURLConnection => x
  case _ => throw new ClassCastException
}

val responseCode = connection.getResponseCode();

val data = try {
  connection.getInputStream()
} catch {
  case e => connection.getErrorStream()
}

val xml = XML.load(data)
return (responseCode, xml)
2 голосов
/ 27 апреля 2011

В http отправке (http://dispatch.databinder.net/About) это можно сделать так:

import dispatch.Http._
import dispatch.{StatusCode, Http}
import xml.XML

try {
  Http("http://localhost/notthere" <> println)
} catch {
  case StatusCode(404, data) =>
    println(XML.loadString(data))
}
1 голос
/ 27 апреля 2011

Для этого уровня управления вы можете использовать ConstructingParser .Пример включен в эту ссылку.Вы получаете необработанный Source и строите из него XML в два отдельных этапа, используя эту технику.

0 голосов
/ 03 ноября 2015

Вот мое решение, которое должно добавить scalaj в проект.

Шаг 1: добавить scalaj в build.sbt (моя версия scala - 2.11.7, но все равно сказано, что моя версия scala была обновлена ​​одной из зависимостей библиотек. Поэтому я добавляю ivyscala для принудительного обновления)

libraryDependencies += "org.scalaj" %% "scalaj-http" % "1.1.4"

ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }

Step2: импортировать библиотеку в код

import scalaj.http.Http
import scala.xml.XML

Step3: использовать http body, чтобы избавиться от 403;добавьте эти коды в часть исключения, когда получите исключение 403.

val response = Http(your_url)
val responseExecute = response.execute()
val responseBody = responseExecute.body.toString
val xml = XML.loadString(responseBody)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...