gpt4 book ai didi

akka - 在 spray-json 中解码嵌套的 json

转载 作者:行者123 更新时间:2023-12-01 16:19:15 24 4
gpt4 key购买 nike

使用 spray-json(因为我使用的是 spray-client)为了从谷歌地图 API 获取纬度、经度对象,我需要设置整个响应结构:

case class AddrComponent(long_name: String, short_name: String, types: List[String])
case class Location(lat: Double, lng: Double)
case class ViewPort(northeast: Location, southwest: Location)
case class Geometry(location: Location, location_type: String, viewport: ViewPort)
case class EachResult(address_components: List[AddrComponent],
formatted_address: String,
geometry: Geometry,
types: List[String])
case class GoogleApiResult[T](status: String, results: List[T])

object AddressProtocol extends DefaultJsonProtocol {
implicit val addrFormat = jsonFormat3(AddrComponent)
implicit val locFormat = jsonFormat2(Location)
implicit val viewPortFormat = jsonFormat2(ViewPort)
implicit val geomFormat = jsonFormat3(Geometry)
implicit val eachResFormat = jsonFormat4(EachResult)
implicit def GoogleApiFormat[T: JsonFormat] = jsonFormat2(GoogleApiResult.apply[T])
}
import AddressProtocol._

有什么方法可以从响应中的 json 中获取 Location 并避免所有这些麻烦事?

spray客户端代码:

implicit val system = ActorSystem("test-system")
import system.dispatcher

private val pipeline = sendReceive ~> unmarshal[GoogleApiResult[EachResult]]

def getPostcode(postcode: String): Point = {
val url = s"http://maps.googleapis.com/maps/api/geocode/json?address=$postcode,+UK&sensor=true"
val future = pipeline(Get(url))
val result = Await.result(future, 10 seconds)
result.results.size match {
case 0 => throw new PostcodeNotFoundException(postcode)
case x if x > 1 => throw new MultipleResultsException(postcode)
case _ => {
val location = result.results(0).geometry.location
new Point(location.lng, location.lat)
}
}
}

或者我如何将 jackson 与 spray-client 一起使用?

最佳答案

按照 jrudolph 对 json-lenses 的建议,我也进行了相当多的摆弄,但终于让事情开始了。我发现这非常困难(作为新手),而且我确信这个解决方案远非最优雅的 - 尽管如此,我认为这可能会帮助人们或激励其他人进行改进。

给定 JSON:

{
"status": 200,
"code": 0,
"message": "",
"payload": {
"statuses": {
"emailConfirmation": "PENDING",
"phoneConfirmation": "DONE",
}
}
}

以及仅用于解码状态的案例类:

case class UserStatus(emailConfirmation: String, phoneConfirmation: String)

可以这样做来解码响应:

import scala.concurrent.Future
import spray.http.HttpResponse
import spray.httpx.unmarshalling.{FromResponseUnmarshaller, MalformedContent}
import spray.json.DefaultJsonProtocol
import spray.json.lenses.JsonLenses._
import spray.client.pipelining._

object UserStatusJsonProtocol extends DefaultJsonProtocol {
implicit val userStatusUnmarshaller = new FromResponseUnmarshaller[UserStatus] {
implicit val userStatusJsonFormat = jsonFormat2(UserStatus)
def apply(response: HttpResponse) = try {
Right(response.entity.asString.extract[UserStatus]('payload / 'statuses))
} catch { case x: Throwable =>
Left(MalformedContent("Could not unmarshal user status.", x))
}
}
}
import UserStatusJsonProtocol._

def userStatus(userId: String): Future[UserStatus] = {
val pipeline = sendReceive ~> unmarshal[UserStatus]
pipeline(Get(s"/api/user/${userId}/status"))
}

关于akka - 在 spray-json 中解码嵌套的 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20078414/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com