Scala create multi-line JSON String Scala create multi-line JSON String json json

Scala create multi-line JSON String


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. Fortunately, Scala's string literals have at least the following properties:

  • 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.
  • The whole construction can be made robust to whitespace and indentation using | and stripMargin.

All together, it allows you to write down arbitrary string literals without ever violating horizontal character limits, in a way that is robust w.r.t. 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.


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:

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:

  • To remove line breaks, use .replaceAll("\\n", "") or rather .replaceAll("\\n", " ")
  • To encode line breaks with the escape sequence \n, use .replaceAll("\\n", "\\\\n") (yes... backslashes...)