6

私は次の関数を書いています:

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)

問題は、応答からのjsonデータを保持することを期待している間、このmyJsonNoneになった後です。

ヘルプ ?

4

3 に答える 3

16

Dispatch には、 JSON を解析するための非常に優れた (そしてあまり宣伝されていない)機能が含まれており、次のように使用できます (失敗した先物を処理するための標準的なアプローチのいずれかを使用して、200 以外の応答を処理できることに注意してください)。

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 ライブラリを使用しており、同様のサポートがLift JSONに対して提供されています (しかし、残念ながらArgonautに対しては何も提供されていませんが、そのようなものを自分で作成するのはそれほど難しくありません)。

于 2013-11-11T11:49:06.573 に答える
7

Http(page OK as.String)HTTP 200 とは異なるすべての応答で Future が失敗するため、使用することはお勧めできません。エラー処理/レポートをより細かく制御する必要がある場合は、代わりに特定のシナリオをターゲットにしてください。

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.
于 2013-11-11T11:22:55.190 に答える
1

次のように、お気に入りの json-library (play-framework-json-lib など) を使用することもできます。

val response = Http(requestUrl OK CarJsonDeserializer)

JsonDeserializer で (Response => Car) トレイトを拡張するだけです。

object CarJsonDeserializer extends (Response => Car) {
  override def apply(r: Response): Car = {
    (dispatch.as.String andThen (jsonString => parse(jsonString)))(r)
  }
}

およびjsonパーサー:

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/

于 2014-11-28T11:36:48.450 に答える