如何在Scala中使用XML.load处理403s?

时间:2011-04-26 22:47:34

标签: xml scala

我正在写Scala client to interface with Amazon's RESTful Product API。要为我正在使用的给定请求返回XML:

XML.load(uri)

这项工作正常,但有时亚马逊不喜欢,例如签名嵌入在uri中,因此返回403(以及有效的XML错误报告)。不幸的是,403在XML.load:{/ p>中抛出异常

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

理想情况下,我想要一种标记异常的方法,但无论如何都要返回错误XML。有没有一种简单的方法可以用XML.load来解决这个问题,或者我是否需要将其分解为两阶段的get-then-load过程?

5 个答案:

答案 0 :(得分:4)

XML.load(URL)使用Java的java.net.URL.openStream(),它以一种不会让您访问“错误流”的方式抛出IOException

因此,您可以进行更长时间的调用以获取InputStream,然后您可以XML.load这个结果的InputStream。

使用URL.openConnection()(而不是URL.openStream),然后从try块中调用HttpURLConnection.getInputStream()。 然后在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

现在,您可以在生成的InputStream上调用XML.load(InputStream)。

希望这足以让你顺利上路。

答案 1 :(得分:2)

在http dispatch(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))
}

答案 2 :(得分:2)

这是我写完的代码,非常感谢上面的所有指导。 (如果下面的任何内容可以改进/更加惯用,请告诉我们):

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)

答案 3 :(得分:1)

对于此级别的控制,您可以使用ConstructingParser。该链接中包含一个示例。您可以使用此技术在两个不同的步骤中获取原始Source并从中构造XML。

答案 4 :(得分:0)

这是我的解决方案,需要将scalaj添加到项目中。

Step1:将scalaj添加到build.sbt(我的scala版本是2.11.7,但它仍然说我的scala版本是由libraray之一更新的。所以我添加了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体来摆脱403;当你得到403异常时,将这些代码添加到异常部分。

val response = Http(your_url)
val responseExecute = response.execute()
val responseBody = responseExecute.body.toString
val xml = XML.loadString(responseBody)