如何解构Spray API HTTPResponse?

时间:2013-07-29 22:41:31

标签: scala solr akka spray

我正在使用Spray API(spray-client)来访问内部Solr URL,我希望能够将响应解析为Scala案例类。

如果我只是期望和HTTPResponse,我得到一个值,但是当我尝试将它编组到我的case类中时,它失败了(我不能生成除null()以外的消息,因为我是使用匹配,显然没有得到正确的测试用例。)

我认为我的一些问题是它以text/plain而不是application/json的形式返回数据。当我期待HttpResponse而不是我的案例类时,

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

我明白了:

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)

但是当我改变它以期待我的案例类时,我无法匹配。那么,我如何编组它返回到Scala案例类的数据呢?这是我尝试过的:

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]

这使我在f onComplete ...结构中无法匹配。问题可能是我的案例类与返回的内容不匹配,如果是,那么你有什么建议可以更好地解决它?

我一直all over the docs而且他们要么不完整还是有点过时,而且我在这场比赛中是新手,所以也没有帮助。

1 个答案:

答案 0 :(得分:6)

我在您的代码中看到的主要问题是您希望mapTo自动将http响应主体解组到您的案例类结构中。 mapTo方法属于Future类,并且不了解json解组。您在Akka请求中使用mapTo?正在幕后执行)基本上“强制转换”Future[Any](这是?的默认响应类型)实际返回的类型。这与json unmarshalling无关。我相信为了达到你想要的效果,你应该创建一个pipeline for spray,它既可以发送请求,也可以解组响应。显示示例的文档是here。我认为对于你的例子,它看起来像这样(代码可能不是100%正确,只是试图显示一般流程):

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