如何将 Scala 列表 [org.bson.Document] 转换为 JSON 字符串?

How do I convert a Scala List[org.bson.Document] to a JSON String?

我在 AWS Lambda 中有一个函数:

def test(pj: Pojo, context: Context): java.util.List[Document]

根本没有使用输入 JSON 值初始化 pj

我发现 another way 像这样在 Scala 中执行 AWS Lambda:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule

val scalaMapper = new ObjectMapper().registerModule(new DefaultScalaModule)

def test(input: InputStream, output: OutputStream): Unit = {
  val inputPojo = scalaMapper.readValue(input, classOf[Pojo])
  val answer: Seq[Document] = getTheRealAnswer(inputPojo)
  val jsonStr = "{ frustration: \"I wish my answer was JSON.\" }"
  output.write(jsonStr.getBytes("UTF-8"))
}

这行得通,除了我真正想要 return 作为答案的是一个 JSON 文档数组。我应该怎么做?

编辑:在我原来的帖子中,我写道:[第一个例子] return 将答案作为错误 22。基本上 AWS(我认为)将 List[Document] 的 JSON 转换视为文件名,JSON 有很多冒号,而错误 22 来自不允许在文件名中使用冒号。很奇怪。” 原来是我从 AWS CLI 调用 AWS Lambda 函数时出错。我在命令调用中省略了输出文件名,returned JSON 被 AWS CLI 解释为文件名。

自从我写了这条消息后,我的工作就变成了这样:

def jsonizeDocs(cDocument: Seq[Document]): String = {
  val sb=new StringBuilder
  for (doc <- cDocument) {
    if (sb.nonEmpty) {
      sb.append(",")
    }
    sb.append(doc.toJson)
  }
  sb.toString
}

注意! 这个答案是基于我围绕 json4s which I call JSON Extensions

写的一个轻包装

假设您使用的是 Scala 对象,请导入 io.onema.json.Extensions._

import io.onema.json.Extensions._

case class Doc(title: String, content: String)

val listOfDocs = Seq(Doc("Foo", "bar"), Doc("Bar", "Baz"), Doc("Blah", "Bax"))
val json: String = listOfDocs.asJson
println(json)  
// [{"title":"Foo","content":"bar"},{"title":"Bar","content":"Baz"},{"title":"Blah","content":"Bax"}]

running example here

现在,由于您使用的是 Pojo,因此需要导入 io.onema.json.JavaExtensions._。假设您有以下 POJO:

public class Document {
 private String title;
 private String content;
 public String getTitle() {return title;}
 public String getContent() {return content;}
 public void setTitle(String title) { this.title = title;}
 public void setContent(String content) {this.content = content;}
}

在您的 Scala 代码中使用此方法,如下所示:

import io.onema.json.JavaExtensions._
import com.example.Document

// ...

def jsonizeDocs(cDocument: Seq[Document]): String = {
  val json: String = cDocument.asJson
  println(json)
  json
}

在 AWS Lambda 中(反之亦然)使用 jsonDecode 和自定义对象映射器反序列化为预期类型:

import io.onema.json.JavaExtensions._
import io.onema.json.Mapper
import com.example.Document

val jsonString = """[{"title":"Foo","content":"bar"},{"title":"Bar","content":"Baz"},{"title":"Blah","content":"Bax"}]"""
val mapper: ObjectMapper = Mapper.allowUnknownPropertiesMapper
val doc: Document = jsonString.jsonDecode[Document](mapper)

我已经在能够反序列化为 AWS lambda 事件以及自定义类型的 lambda 框架中非常成功地使用了此处描述的方法,请参阅 simple example here

就是这样!您可以使用此库或 Java 或 Scala 中的众多 JSON 序列化程序之一。如果您知道对象的类型,大多数库将使您能够非常轻松地序列化到 JSON 并返回。