我正在写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过程?
答案 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)