代码之家  ›  专栏  ›  技术社区  ›  yiksanchan

json4s:跨场提取

  •  0
  • yiksanchan  · 技术社区  · 6 年前

    extract 基于中定义的每类型规则的JsonAST DefaultFormats CustomSerializer

    有时我想进行跨场提取。例如,给定一个json字符串 {"a": 1, "b": 2} ,我想设置 b 进入之内 a+b

    import org.json4s._
    import org.json4s.native.JsonMethods._
    import org.json4s.JsonAST._
    
    case class A(a: Int, b: Int)
    
    case object ACustomSerializer extends CustomSerializer[A](
        format =>
        ({
            case jo: JObject =>
                val a = (jo \ "a").extract[Int]
                val b = (jo \ "b").extract[Int] + a
                A(a, b)
        }, Map())
    )
    
    implicit val formats = DefaultFormats + ACustomSerializer
    
    parse("""{"a": 1, "b": 2}""").extract[A] // A(1,3)
    

    但是,如果 case class A 如果有许多其他字段,则很难为所有字段编写规则。

    case class A(a: Int, b: Int, c: Int, d: Int)
    
    case object ACustomSerializer extends CustomSerializer[A](
        format =>
        ({
            case jo: JObject =>
                val a = (jo \ "a").extract[Int]
                val b = (jo \ "b").extract[Int] + a
                val c = ...
                val d = ...
                A(a, b, c, d)
        }, Map())
    )
    

    或其他 b

    有没有办法只为特殊字段编写规则,而让其他字段由 CustomSerialzer ?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Tim    6 年前

    separation of concerns ).

    val a = parse("""{"a": 1, "b": 2}""").extract[A] // A(1,2)
    
    a.copy(b = a.a + a.b) // A(1,3)
    

    在更复杂的情况下,处理后的数据的布局将不同于解析后的数据,因此您将需要第二个 case class 它描述了原始数据和将其转换为已处理格式的函数。虽然这看起来很麻烦,但它会使代码更容易理解,更易于修改。

    推荐文章