2013-07-29 13 views
8

Używam Spray API (spray-client) do trafienia w wewnętrzny adres URL Solr, chcę móc przeanalizować odpowiedź w klasie przypadku Scala.Jak mogę zrekonstruować API HTTPResponse Spray?

Jeśli po prostu oczekuję i HTTPResponse, otrzymuję wartość z powrotem, ale kiedy próbuję wprowadzić ją do mojej klasy spraw, nie działa (nie mogę wygenerować komunikatu innego niż null(), ponieważ " m za pomocą dopasowywania i oczywiście nie uzyskanie prawidłowego przypadku testowego.)

Myślę, że niektóre z moich problemów jest to, że zwraca dane w postaci text/plain zamiast application/json. Kiedy spodziewać HttpResponse zamiast moją klasę case,

val f: Future[HttpResponse] = 
    (IO(Http) ? Get("http://1.2.3.4:8983/solr/collection1/select?q=*%3A*&wt=json")).mapTo[HttpResponse] 

uzyskać:

HttpResponse(200 OK,HttpEntity(text/plain; charset=UTF-8, 
{ 
    "responseHeader":{"status":0,"QTime":65,"params":{"q":"*:*","wt":"json"}}, 
    "response":{"numFound":147437873,"start":0,"maxScore":1.0,"docs": 
    [ 
     {"guid":"TLQ0jVlMYCXQrYkBIZHNXfMmifw+3","alias":["greg"],"_version_":1440942010264453120}, 
     {"guid":"TQsDY1ZG7q+Ne5e6F7qAUhFyomSH9","_version_":1440942010296958976}, 
     {"guid":"TzWB5grOBAJJZcAQDo2k9xBUVGPFr","alias":["spark"],"_version_":1440942010298007552}, 
     {"guid":"T0judCG4UI9RYqDDQVcn+gyZEU7Bb","alias":["zombie"],...),List(Connection: close, Content-Type: text/plain; charset=UTF-8),HTTP/1.1) 

Ale kiedy zmieni się spodziewać moją klasę razie nie może się równać. Jak więc zmusić dane, które powróciły do ​​klasy przypadków Scala? Oto co próbowałem:

case class SolrParams(q: String, wt: String) 
case class SolrResponseHeader(status: String, qtime: String, params: SolrParams) 
case class SolrDoc(guid: String, alias: List[String], version: String) 
case class SolrResponse(numFound: Long, start: Long, maxScore: String, docs: List[SolrDoc]) 

case class SolrApResult(responseHeader: SolrResponseHeader, response: SolrResponse) 

object SolrJsonProtocol extends DefaultJsonProtocol { 
    implicit val paramsFormat = jsonFormat2(SolrParams) 
    implicit val responseHeaderFormat = jsonFormat2(SolrResponseHeader) 
    implicit val docFormat = jsonFormat3(SolrDoc) 
    implicit val responseFormat = jsonFormat4(SolrResponse) 
    implicit def solrApiResultFormat = jsonFormat2(SolrApiFullResult) 
} 

... 

val f: Future[SolrApiResult] = 
    (IO(Http) ? Get("http://1.2.3.4:8983/solr/collection1/select?q=*%3A*&wt=json")).mapTo[SolrApiResult] 

co daje mi nie pasuje w strukturze f onComplete .... Czy problem może wynikać z tego, że moje klasy przypadków nie pasują do tego, co jest zwracane, a jeśli tak, jakie sugestie masz do rozwiązania tego problemu?

Byłem niekompletny lub nieco przestarzały, a także jestem nowy w tej grze, więc to też nie pomaga.

Odpowiedz

6

Głównym problemem, który widzę w twoim kodzie, jest to, że spodziewasz się, że mapTo automatycznie odrzuci ciało odpowiedzi http na twoją strukturę klasy spraw. Metoda mapTo należy do klasy Future i nie ma pojęcia o json unmarshalling. Używasz mapTo w ramach żądania Akka (które ? wykonuje pod maską), aby zasadniczo "rzucić" Future[Any] (który jest domyślnym typem odpowiedzi z) na typ, który zostanie faktycznie zwrócony. To nie ma nic wspólnego z json unmarshalling. Wierzę, że aby osiągnąć to, co chcesz, powinieneś stworzyć pipeline dla sprayu, który zarówno wyśle ​​żądanie, jak i odrzuci odpowiedź. Dokumentacja pokazująca przykłady tego są here. Myślę, że dla przykładu, to będzie wyglądać mniej więcej tak (kod nie może być w 100% rację, po prostu staramy się pokazać ogólny przepływ):

val pipeline = sendReceive ~> unmarshall[SolrApiResult] 
val response:Future[SolrApiResult] = pipeline(Get("http://1.2.3.4:8983/solr/collection1/select?q=*%3A*&wt=json")) 
+0

Ok to dobrze wiedzieć - ja sądziłem '.mapTo' miał dodatkowa magia, której najwyraźniej nie ma. Dziękuję – jbnunn

+0

@cmbaxter, połączone 'tutaj' nie istnieje teraz. –

+1

@KevinMeredith, zaktualizowałem link – cmbaxter

Powiązane problemy