首页 > 解决方案 > 如何一起使用 Circe Optics 和 Decode

问题描述

我正在使用这样的圆形光学器件

import io.circe.parser._
import io.circe.optics._
import io.circe.optics.JsonPath._

val json = parse("""{"response": {"person": {"firstname": "foo", "lastname":"bar"}}}""").right.get

现在我想以字符串形式提取整个人对象......从这个json中提取

val p = root.response.person.string

然后将其解码为一个案例类

case class Person(firstname: String, lastname: String)
decode[Person](p.getOption(json).get)

但它不起作用,因为root.response.person.string返回 null。我认为它只适用于实际的字符串和整数列。

那么可以使用 circe optics 来提取 json 的整个部分(例如 json 中的 person 对象)吗?然后将该部分解码为案例类?

标签: scalacirce

解决方案


这样就搞定了。无需在两者之间获取字符串,只需使用Json

object Some extends App {

  import io.circe.optics.JsonPath._
  import io.circe.parser._
  import io.circe._
  import io.circe.generic.semiauto._

  val json = parse("""{"response": {"person": {"firstname": "foo", "lastname":"bar"}}}""").right.get

  // this is just a lense to the person, not the person yet
  val personJsonPath = root.response.person.json

  case class Person(firstname: String, lastname: String)
  implicit val personDecoder: Decoder[Person] = deriveDecoder[Person]

  val maybePerson = personJsonPath
    // here you get the person out
    .getOption(json)
    // transforming json directly to case class, error handling should not be done like this ;)
    .map(_.as[Person].fold(throw _, identity))

  println(maybePerson)
}

推荐阅读