Update 2023: I don't know why anyone would bother generating JSON manually in 2023. Just use some appropriate library that knows how to serialize stuff to JSON.
(original answer)
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...)