我有一个像这样的JSON:
{
"switch": "foo",
"items": [
{"type": "one"},
{"type": "two"}
]
}
我想将它加载到类的结构中:
case class MyFile(
@JsonProperty("switch") _switch: String,
@JsonProperty("items") _items: JList[Item],
) {
val items: List[Item] = _items.toList
}
case class Item(t: String)
object Item {
@JsonCreator
def create(@JsonProperty("type") _type: String): Item = {
Item(t) // <= conversion
}
}
诀窍是我想要转换传入&#34;类型&#34;具有某种功能的字符串,它将取决于&#34; switch&#34;的值。最简单的例子就是
def create(@JsonProperty("type") _type: String): Item = {
Item(t + "_" + switchValue)
}
但是,在解析内部(即在构造函数或@JsonCreator
静态方法中),我似乎找不到访问JSON树部分的方法。
到目前为止,我唯一提到的基本上是一个全局变量,如:
case class MyFile(
@JsonProperty("switch") _switch: String,
@JsonProperty("items") _items: JList[Item],
) {
MyFile.globalSwitch = _switch
val items: List[Item] = _items.toList
}
object MyFile {
var globalSwitch = ""
}
case class Item(t: String)
object Item {
@JsonCreator
def create(@JsonProperty("type") _type: String): Item = {
Item(t + "_" + MyFile.globalSwitch) // <= conversion
}
}
它有效,但它显然相当丑陋:例如,你不能并行解析具有不同开关值的2个文件,等等。有更好的解决方案吗?例如,也许我可以访问某种per-ObjectMapper或每个解析上下文,我可以存储这个设置吗?
答案 0 :(得分:1)
我认为这会对您有所帮助:https://github.com/spray/spray-json
import spray.json._
case class NamedList[A](name: String, items: List[A])
case class Item(t: String)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit def namedListFormat[A :JsonFormat] = jsonFormat2(NamedList.apply[A])
implicit val ItemDTO = jsonFormat1(Item.apply)
}
import MyJsonProtocol._
val list = NamedList[Item](name = "Alex", items = Item("Moran")::Item("Sem")::Nil)
val res = list.toJson.toString()
val parse = res.parseJson.convertTo[NamedList[Item]]
RES:
res: String =
{
"name":"Alex",
"items":
[
{"t":"Moran"},
{"t":"Sem"}
]
}
解析:
parse: NamedList[Item] = NamedList(Alex, List(Item(Moran), Item(Sem)))
切换器可以像~~
implicit class Switcher[A <: Item](data: NamedList[A]){
def getEr = data.name match{
case "Jone" => ("It`s Jone", data)
case "Alex" => ("It`s Alex", data)
}
def getErFunc[T](func : (NamedList[A], String) => T) =
data.name match{
case "Jone" => ("It`s Jone", func(data , "Param"))
case "Alex" => ("It`s Alex", func(data, "Not Param"))
}
}
val res2 = parse.getEr
val res3 = parse.getErFunc((f, s) => (f.items.size, s.toUpperCase))
res:
res2: (String, NamedList[Item]) =
(It`s Alex,NamedList(Alex,List(Item(Moran), Item(Sem))))
res3: (String, (Int, String)) = (It`s Alex,(2,NOT PARAM))