[英]Representing a list of JSON tuples as a case class field, with Json4s
给定以下JSON:
{
"foo": "bar",
"baz":[
{ "qux" : "quux" },
{ "quuux" : "quuuux" }
]
}
将其表示为Scala案例类的最佳方法是什么? 逻辑上似乎应该是这样的:
case class Foo(
foo: String,
baz: List[(String, String)]
)
但是,当我尝试用Json4s和Jackson解析它时,我得到:
No usable value for baz
No usable value for _1
Did not find value which can be converted into java.lang.String
org.json4s.package$MappingException: No usable value for baz
No usable value for _1
Did not find value which can be converted into java.lang.String
如果我构建预期的Foo
,则朝另一个方向前进...
val foo = Foo(foo = "bar", baz = List(("qux" -> "qux1"), ("qux" -> "qux2")))
...并将其写为JSON,我没有得到元组列表,得到:
{
"foo" : "bar",
"baz" : [ {
"_1" : "qux",
"_2" : "qux1"
}, {
"_1" : "qux",
"_2" : "qux2"
} ]
}
我在这个答案中看到,尽管Json4s 声称可以从DSL中的Tuple2s
中产生对象,但是除非该对象字段被定义为JValue
否则它实际上不能对一个对象字段进行JValue
。 由于除了序列化和反序列化之外,我还想对Foo
模型对象执行其他操作,因此我特别不想根据JValues
定义它。
鉴于此,我应该在这里做什么?
我看到至少两个选择如何处理此问题:
有时,直接在AST上运行或通过values函数提取纯Map [String,Any]也很有用。 只要您正在使用JValue DSL,Tuple2转换就有效,但是从Scala类型提取/分解时无效。
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.JsonDSL._
val json = """{
| "foo": "bar",
| "baz":[
| { "qux" : "quux" },
| { "quuux" : "quuuux" }
| ]
|}""".stripMargin
class StringTupleSerializer extends CustomSerializer[(String, String)](format => ( {
case JObject(List(JField(k, JString(v)))) => (k, v)
}, {
case (s: String, t: String) => (s -> t)
}))
implicit val formats = DefaultFormats + new StringTupleSerializer
case class FooMap(foo: String, baz: List[Map[String, String]])
case class FooTuple(foo: String, baz: List[(String, String)])
val ast = parse(json)
println(ast.extractOpt[FooMap])
// Some(FooWithMap(bar,List(Map(qux -> quux), Map(quuux -> quuuux))))
println(ast.extractOpt[FooTuple])
// Some(FooWithTuple(bar,List((qux,quux), (quuux,quuuux))))
val foo1 = FooMap(foo = "bar", baz = List(Map("qux" -> "qux1"), Map("qux" -> "qux2")))
val foo2 = FooTuple(foo = "bar", baz = List(("qux" -> "qux1"), ("qux" -> "qux2")))
println(pretty(Extraction.decompose(foo1)))
println(pretty(Extraction.decompose(foo2)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.