我正在编写一个函数:
1)发送HTTP GET请求(响应是有效的JSON)
2)解析对json对象的响应
代码段:
val page = url("http://graph.facebook.com/9098498615")
val response = Http(page OK dispatch.as.String)
Await.result(response , 10 seconds)
val myJson= JSON.parseFull(response .toString)
//this isnt helping -> val myJson= JSON.parseRaw(response .toString)
问题出在此 myJson 无之后,我希望它能够保留响应中的json数据。
帮助?
答案 0 :(得分:16)
Dispatch包含一些非常好的(并且广告不足)facilities for parsing JSON,您可以像这样使用(请注意,您可以使用任何标准方法处理非200个响应来处理失败的期货):< / p>
import dispatch._
import org.json4s._, org.json4s.native.JsonMethods._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{ Failure, Success }
val page = url("http://graph.facebook.com/9098498615")
val response = Http(page OK dispatch.as.json4s.Json)
response onComplete {
case Success(json) => println(json \ "likes")
case Failure(error) => println(error)
}
此示例使用Json4s library,并为Lift JSON提供了类似的支持(但遗憾的是Argonaut没有,尽管自己编写这样的东西并不太难)。
答案 1 :(得分:5)
使用Http(page OK as.String)
不是一个好主意,因为所有与HTTP 200不同的响应都会导致Futures失败。如果您需要对错误处理/报告进行更细粒度的控制,请改为针对特定方案。
import org.jboss.netty.handler.codec.http.{ HttpRequest, HttpResponse, HttpResponseStatus }
def getFacebookGraphData: Either[Exception, String] = {
val page = url("http://graph.facebook.com/9098498615")
val request = Http(page.GET);
val response = Await.result(request, 10 seconds);
(response.getStatusCode: @annotation.switch) match {
case HttpResponseStatus.OK => {
val body = response.getResponseBody() // dispatch adds this method
// if it's not available, then:
val body = new String(response.getContent.array);
Right(body)
}
// If something went wrong, you now have an exception with a message.
case _ => Left(new Exception(new String(response.getContent.array)));
}
}
默认的Scala JSON库也不是一个好主意,它与其他库相比非常粗糙。例如,尝试lift-json
。
import net.liftweb.json.{ JSONParser, MappingException, ParseException };
case class FacebookGraphResponse(name: String, id: String);// etc
implicit val formats = net.liftweb.DefaultFormats;
val graphResponse = JSONParser.parse(body).extract[FacebookGraphResponse];
// or the better thing, you can catch Mapping and ParseExceptions.
答案 2 :(得分:1)
你也可以使用你自己喜欢的json-library(例如play-framework-json-lib):
val response = Http(requestUrl OK CarJsonDeserializer)
你只需通过JsonDeserializer扩展(Response =&gt; Car)特征。
object CarJsonDeserializer extends (Response => Car) {
override def apply(r: Response): Car = {
(dispatch.as.String andThen (jsonString => parse(jsonString)))(r)
}
}
和json-parser:
implicit val carReader: Reads[Car] = (
(JsPath \ "color").read[String] and
(JsPath \ "model").read[String]
)(Monitor.apply _)
private def parse(jsonString: String) = {
val jsonJsValue = Json.parse(jsonString)
jsonJsValue.as[Car]
}
请参阅此博客文章:https://habashics.wordpress.com/2014/11/28/parsing-json-play-lib-with-dispatch/