将任何Scala对象转换为JSON

20

我正在使用最新版的Play框架和其JSON库,像这样 Json.toJson(obj)。但是toJson无法将任何Scala对象转换为JSON,因为数据结构是未知的。有人建议使用case convert,但我的Scala知识不足。数据来自数据库,但表的结构不是已知的。

我该在哪里寻找进一步创建将此类未知数据结构转换为JSON的转换器呢?


使用 Format[T] 怎么样?(请参见 http://www.playframework.com/documentation/2.2.x/ScalaJsonCombinators)但是,您必须在编译时知道 T 的类型,尽管从问题中我不确定这是否会成为一个问题。 - tehlexx
谢谢提供的链接,我查看了Format[T]选项,但似乎需要知道数据结构才能使用它。但是当我将数据库中的结果转换为Map时,结构是[String,Any] - 基本上是未知的。 - Vilis
我使用asMap将数据映射到格式[String,Any],但是当尝试使用toJson转换这样的结构时,Scala会抛出错误 - No Json serializer found for type List[scala.collection.Map[String,Any]] - Vilis
如果Any部分仅限于某些类型,如StringInt等,则可以使用模式匹配和显式转换这些类型。但是,您需要为要序列化的每种类型都需要一个case行。 - tehlexx
是的,它只限于某些类型。这正是我想要的。你能给我一些例子吗? - Vilis
2个回答

8
鉴于您只想将有限的类型序列化为JSON,因此可以采用以下方法:

给定以下内容:

object MyWriter {
  implicit val anyValWriter = Writes[Any] (a => a match {
    case v:String => Json.toJson(v)
    case v:Int => Json.toJson(v)
    case v:Any => Json.toJson(v.toString)
    // or, if you don't care about the value
    case _ => throw new RuntimeException("unserializeable type") 
  })
}

您可以通过在想要序列化Any的点导入隐式值来使用它:

import MyWriter.anyValWriter
val a: Any = "Foo"
Json.toJson(a)

谢谢,这几乎是完美的解决方案。您如何捕获任何不是字符串或整数的值?它可以转换为字符串或完全忽略。 - Vilis
谢谢!现在有另一个问题,List和Map被转换为字符串。在JSON中的最终结果就是这个字符串“"List(Map(users.id -> 1, users.status -> 1))"”。 - Vilis
是的,您需要为所有要序列化的类型添加case行,包括像ListMap这样的集合。这就是为什么这种方法只适用于您想要支持有限数量的类型。 - tehlexx
没错,这不是什么大问题,因为只有一个List和Map。我尝试像这样添加“List”:“case v: List => Json.toJson(v)”,但它没有起作用,因为“错误:类型List需要类型参数”。此外,是否可能仅针对数据集的特定部分使用anyValWriter,其中实际需要进行类型匹配,以基本上避免List和Map部分? - Vilis
我找到了解决我之前评论中提到的问题的方法。我使用了JsArray和JsObject来避免对Map和List进行Json.toJson。现在它可以运行了,但我不确定这是否是一个正确的做法。 - Vilis
1
但这并没有回答一般性问题。我有一个对象,但我不知道它是什么。我知道它非常复杂,有很多字段、列表、映射和嵌套对象。我不在乎这些。我只想要所有的东西都像在C#或Java中一样以JSON格式呈现。 - Joel Peltonen

2
使用json4s,您可以导入该包:

使用json4s,您可以导入以下软件包:

import org.json4s.DefaultFormats
import org.json4s.native.Serialization.write

然后在你的trait内部创建一个隐式变量:

implicit val formats: DefaultFormats = DefaultFormats

"最初的回答"翻译成英文是 "Original Answer"。最后,在您的方法中使用它:
write(myObject)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接