Scala创建多行JSON字符串

cov*_*efe 5 json scala string-formatting

我正在尝试在Scala中创建多行字符串,如下所示。

val errorReport: String =
    """
      |{
      |"errorName":"blah",
      |"moreError":"blah2",
      |"errorMessage":{
      |         "status": "bad",
      |         "message": "Unrecognized token 'noformatting': was expecting 'null', 'true', 'false' or NaN
 at [Source: (ByteArrayInputStream); line: 1, column: 25]"
      | }
      |}
      """
   .stripMargin
Run Code Online (Sandbox Code Playgroud)

这是一个嵌套的JSON,在我打印时无法正确显示。message内部的字段errorMessage(调用getMessage的实例的输出Throwable)引起问题,因为它看起来像在前面有换行符一样

at [Source: ...

如果我摆脱了这一行,JSON将正确显示。任何有关如何正确格式化此格式的想法都将受到赞赏。

编辑:问题是换行符。因此,我认为问题更为简洁-如何在三重引号中处理换行符,以便仍将其识别为JSON?

编辑2:message由像这样的变量设置:

"message": "${ex.getMessage}"

哪里exThrowablegetMessage上面提供了该呼叫的内容示例。

And*_*kin 5

2023 年更新:我不知道为什么有人会在 2023 年费心手动生成 JSON。只需使用一些知道如何将内容序列化为 JSON 的适当库即可。


(原答案)

我假设您的问题与 JSON 无关,您只是询问如何创建非常宽的字符串而不违反 Scala 代码中的水平 80 个字符限制。幸运的是,Scala 的字符串文字至少具有以下属性:

  • "..."您可以使用引号和三重引号从普通代码转到字符串文字模式"""..."""
  • 您可以使用以下命令从字符串文字模式转到普通代码模式${...}
  • 字符上的自由幺半群被具体化为方法,即存在+连接字符串文字的操作。
  • |使用和可以使整个结构对空白和缩进变得稳健stripMargin

总之,它允许您以一种健壮的缩进方式写下任意字符串文字,而不会违反水平字符限制。

在这种特殊情况下,您希望在环境 scala 代码中进行换行,而不在文本中引入换行符。为此,您只需

  • 通过关闭退出字符串文字模式"""
  • +在代码模式下插入串联运算符
  • 换行
  • 随心所欲地缩进
  • 通过打开再次重新进入字符串文字模式"""

那是,

"""blah-""" +
"""blah"""
Run Code Online (Sandbox Code Playgroud)

将创建 string "blah-blah",在生成的字符串中没有换行符。


应用于您的具体问题:

val errorReport: String = (
    """{
      |  "errorName": "blah",
      |  "moreError": "blah2",
      |  "errorMessage": {
      |    "status": "bad",
      |    "message": "Unrecognized token 'noformatting'""" +
    """: was expecting 'null', 'true', 'false' or NaN at """ +
    """[Source: (ByteArrayInputStream); line: 1, column: 25]"
      |  }
      |}
      """
  ).stripMargin
Run Code Online (Sandbox Code Playgroud)

也许更易读的选择是从整齐缩进的 JSON 中单独构造冗长的消息,然后使用字符串插值来组合这两个组件:

val errorReport: String = {
  val msg = 
    """Unrecognized token 'noformatting': """ +
    """was expecting 'null', 'true', 'false' or NaN at """ +
    """[Source: (ByteArrayInputStream); line: 1, column: 25]"""

    s"""{
      |  "errorName": "blah",
      |  "moreError": "blah2",
      |  "errorMessage": {
      |    "status": "bad",
      |    "message": "${msg}"
      |  }
      |}
      """
  }.stripMargin
Run Code Online (Sandbox Code Playgroud)

如果消息本身包含换行符

由于 JSON 不允许多行字符串文字,因此您必须执行其他操作:

  • 要删除换行符,请使用.replaceAll("\\n", "")或者.replaceAll("\\n", " ")
  • 要使用转义序列对换行符进行编码\n,请使用.replaceAll("\\n", "\\\\n")(是的...反斜杠...)