I'm trying to create a multi-line String in Scala as below.
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. 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
at [Source: ...
.
If I get rid of that line the JSON displays properly. 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?
EDIT 2: message
is being set by a variable like so:
"message": "${ex.getMessage}"
where ex
is a Throwable
. An example of the contents of that getMessage
call is provided above.
JSON does not allow "real" newlines in its data; it can only have escaped newlines. See the answer from @YOU. According to the question, it looks like you attempted to escape line breaks in Python two ways: by using the line continuation character ( "\" ) or by using "\n" as an escape.
Now you can store multiline strings and get results in JSON single line. It's not the prettiest thing, but it is the simplest given the constraints of JSON.
JSON strings do not allow real newlines in its data; it can only have escaped newlines.
Spark JSON data source API provides the multiline option to read records from multiple lines. By default, spark considers every record in a JSON file as a fully qualified record in a single line hence, we need to use the multiline option to process JSON from multiple lines.
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:
"..."
and triple quotes """..."""
.${...}
+
operation that concatenates string literals.|
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
"""
+
in code mode"""
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:
.replaceAll("\\n", "")
or rather .replaceAll("\\n", " ")
\n
, use .replaceAll("\\n", "\\\\n")
(yes... backslashes...)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With