简体   繁体   English

Scala创建多行JSON字符串

[英]Scala create multi-line JSON String

I'm trying to create a multi-line String in Scala as below. 我正在尝试在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

It's a nested JSON and it's not displaying properly when I print it. 它是一个嵌套的JSON,当我打印它时它没有正确显示。 The message field inside errorMessage (which is the output of calling getMessage on an instance of a Throwable ) is causing the issue because it looks like there is a newline right before errorMessagemessage字段(这是在Throwable实例上调用getMessage的输出)导致问题,因为它看起来好像之前有一个换行符

at [Source: ... . at [Source: ...

If I get rid of that line the JSON displays properly. 如果我摆脱那条线,JSON会正确显示。 Any ideas on how to properly format this are appreciated. 任何有关如何正确格式化这一点的想法都值得赞赏

EDIT: The issue is with the newline character. 编辑:问题在于换行符。 So I think the question is more concisely - how to handle the newline within the triple quotes so that it's still recognized as a JSON? 所以我认为问题更简洁 - 如何处理三重引号中的换行符,以便它仍然被识别为JSON?

EDIT 2: message is being set by a variable like so: 编辑2: message由变量设置如下:

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

where ex is a Throwable . 其中exThrowable An example of the contents of that getMessage call is provided above. 上面提供了该getMessage调用的内容示例。

I assume that your question has nothing to do with JSON, and that you're simply asking how to create very wide strings without violating the horizontal 80-character limit in your Scala code. 我假设您的问题与JSON无关,并且您只是询问如何创建非常宽的字符串而不违反Scala代码中的水平80字符限制。 Fortunately, Scala's string literals have at least the following properties: 幸运的是,Scala的字符串文字至少具有以下属性:

  • You can go from ordinary code to string-literal mode using quotes "..." and triple quotes """...""" . 您可以使用引号"..."和三引号"""..."""从普通代码转换为字符串文字模式。
  • You can go from string-literal mode to ordinary code mode using ${...} 你可以使用${...}从字符串文字模式转换到普通代码模式
  • Free monoid over characters is reified as methods, that is, there is the + operation that concatenates string literals. 字符上的自由monoid被称为方法,也就是说,存在连接字符串文字的+操作。
  • The whole construction can be made robust to whitespace and indentation using | 使用|可以使整个结构对空白和缩进具有鲁棒性 and stripMargin . stripMargin

All together, it allows you to write down arbitrary string literals without ever violating horizontal character limits, in a way that is robust wrt indentation. 总而言之,它允许您在不违反水平字符限制的情况下写下任意字符串文字,其方式是强健的缩进。

In this particular case, you want to make a line break in the ambient scala code without introducing a line break in your text. 在这种特殊情况下,您希望在环境标量代码中进行换行,而不在文本中引入换行符。 For this, you simply 为此,你干脆

  • exit the string-literal mode by closing """ 通过关闭"""退出字符串文字模式
  • insert concatenation operator + in code mode 在代码模式下插入连接运算符+
  • make a line-break 换线
  • indent however you want 但是你想要缩进
  • re-enter the string-literal mode again by opening """ 通过打开"""再次重新进入字符串 - 文字模式

That is, 那是,

"""blah-""" +
"""blah"""

will create the string "blah-blah" , without line break in the produced string. 将创建字符串"blah-blah" ,在生成的字符串中没有换行符。


Applied to your concrete problem: 适用于您的具体问题:

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

Maybe a more readable option would be to construct the lengthy message separately from the neatly indented JSON, and then use string interpolation to combine the two components: 也许更可读的选择是从整齐的缩进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

If the message itself contains line breaks 如果邮件本身包含换行符

Since JSON does not allow multiline string literals, you have to do something else: 由于JSON不允许多行字符串文字,因此您必须执行其他操作:

  • To remove line breaks, use .replaceAll("\\\\n", "") or rather .replaceAll("\\\\n", " ") 要删除换行符,请使用.replaceAll("\\\\n", "")或更确切地说.replaceAll("\\\\n", " ")
  • To encode line breaks with the escape sequence \\n , use .replaceAll("\\\\n", "\\\\\\\\n") (yes... backslashes...) 要使用转义序列\\n编码换行符,请使用.replaceAll("\\\\n", "\\\\\\\\n") (是...反斜杠......)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM