2011-04-26 6 views
1

나는 Scala client to interface with Amazon's RESTful Product API을 쓰고있다. 주어진 요청에 대한 XML을 반환하려면 다음을 사용합니다.Scala에서 XML.load를 사용하여 403을 처리 할 수 ​​있습니까?

XML.load(uri) 

아마존이 좋아하지 않는 경우를 제외하고는 잘 작동합니다. uri에 서명이 포함되어 있으므로 유효한 XML 오류 보고서와 함께 403을 반환합니다. 불행하게도이 403 XML.load 내에서 예외가 발생합니다 :

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

가 이상적으로 예외를 신고 어쨌든 오류 XML을 반환하는 방법을 싶습니다. XML.load으로이 작업을 수행 할 수있는 간단한 방법이 있습니까? 아니면 두 단계의 get-then-load 프로세스로 분해해야합니까?

답변

4

은 XML.load (URL)는 당신에게 "오류 스트림"

에 대한 액세스 권한을 부여하지 않는 방법으로 IOException가 던지고 자바의 java.net.URL.openStream()를 사용합니다 따라서 InputStream을 얻기 위해 좀 더 길어진 호출 순서를 만들 수 있습니다. 그런 다음 결과 InputStream을 XML.load 할 수 있습니다.

URL.openStream 대신 URL.openConnection()을 사용하고 try 블록 내에서 HttpURLConnection.getInputStream()을 호출하십시오. catch 블록에서 HttpURLConnection.getErrorStream()을 호출하십시오.

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

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

이제 당신은 결과의 InputStream에은 XML.load (의 InputStream)를 호출 할 수 있습니다.

당신의 길을 가기에 충분합니다. HTTP 파견에서

+0

많은 감사를 그 PrettyPrinter 코드를 차용하고있다 - 당신이 제안 어떻게 정확하게 구현하고 있습니다. –

1

이 제어 수준의 경우 ConstructingParser을 사용할 수 있습니다. 예제는 해당 링크에 포함되어 있습니다. 이 기술을 사용하여 원시 Source을 가져 와서 두 가지 단계로 XML을 구성합니다.

+0

도움 예, 감사합니다 -지도를 위해 ... 내 API에 디버그() 메서드 –

2

은 (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)) 
} 
+0

감사합니다. Scala Dispatch에 대해 들어 보지 못했습니다. 흥미 롭습니다. –

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) 
0

여기 프로젝트 scalaj를 추가 할 필요가 내 솔루션입니다.

1 단계 :

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

ivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) } 
(. 그래서 난 ivyscala이 업데이 트를 강제로 추가 내 스칼라 버전 2.11.7이지만, 여전히 내 스칼라 버전 libraray dependcies 중 하나에 의해 업데이트 된 말했다) build.sbt하는 scalaj를 추가

2 단계 : 코드 가져 오기 라이브러리

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

3 단계 : 사용 HTTP 본문 (403)을 제거하는 단계; 403 예외가 발생하면 예외 코드에이 코드를 추가하십시오.

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