2013-11-11 3 views
5

IM писать функцию, которая:Scala запрос отправки GET, не разобрать ответ на JSon

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 от ответа.

Помощь?

+1

нет ошибки .. только что myJson не None, а не им ответа JSON ожидает – Nimrod007

ответ

5

Это не рекомендуется использовать Http(page OK as.String), потому что все ответы, отличные от HTTP 200, приведут к неудачным фьючерсам. Если вам нужен более мелкозернистый контроль над обработкой ошибок/отчетами, вместо этого укажите конкретные сценарии.

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

Это не действительно, истинно, что 'OK' означает« пренебрежение »всеми ответами, отличными от 200, - это возвращает« Будущее », которое не получило бы ответа на эти ответы, но часто это именно то, что вы хотите. Вы все равно можете обрабатывать не-200 ответов. –

+0

Надеюсь, вы не возражаете, что я добавил свой собственный ответ, используя поддержку «встроенного» (как подпроекта) «Диспетчера» JSON. –

16

Отправка включает в себя некоторые очень приятно (и под рекламируемым) facilities for parsing 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 library, и подобная поддержка предоставляется Lift JSON (но, к сожалению, ничего для Argonaut, хотя это не слишком сложно писать такие вещи самостоятельно).

+2

Я всегда получаю 'объект json4s не является членом пакета dispatch.as'. Редактирование: просто понял, что мне пришлось добавить зависимость от моего build.sbt http://mvnrepository.com/artifact/net.databinder.dispatch/dispatch-json4s-native_2.10/0.11.1 – joslinm

+2

@joslinm не могли бы вы быть более точно, что вы добавили в свой build.sbt? У меня была та же проблема, добавлена ​​зависимость, но все еще проблема. –

+6

'" net.databinder.dispatch "%" dispatch-json4s-native_2.11 "%" 0.11.1 "' – joslinm

1

Вы также можете использовать ур собственный любимый JSon-библиотеку (например, плей-каркасного JSON-Lib), как это:

val response = Http(requestUrl OK CarJsonDeserializer) 

U имеют только продлить (Response => Car) черта самая JsonDeserializer.

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/

 Смежные вопросы

  • Нет связанных вопросов^_^