15

I'm trying to put a json in a javascript file in java, but when I write the json to a string, the string doesn't appear to be a valid json for javascript; it is missing some escapes. (This is happening in a string in the json which I formatted as a faux json.)

For example, this would be a valid json in my javascript file:

{
   "message": 
   "the following books failed: [{\"book\": \"The Horse and his Boy\",\"author\": \"C.S. Lewis\"}, {\"book\": \"The Left Hand of Darkness\",\"author\": \"Ursula K. le Guin\"}, ]"
}

Here's what I get, though, where the double quotes aren't escaped:

{
   "message": 
   "The following books failed: [{"book": "The Horse and his Boy","author": "C.S. Lewis"}, {"book": "The Left Hand of Darkness","author": "Ursula K. le Guin"}, ]"
}

I get the second result when I do this:

new ObjectMapper().writer().writeValueAsString(booksMessage);

But when I write it directly to a file with jackson, I get the first, good result:

new ObjectMapper().writer().writeValue(fileToWriteTo, booksMessage);

So why does jackson escape differently when writing to a file, and how do I get it to escape like that for me when writing to a string?

CorayThan
  • 17,174
  • 28
  • 113
  • 161
  • Your "valid json" is a weird format. Why do you have what looks like an array embedded in the same string as `"The following books failed:...`? – nnnnnn Nov 09 '13 at 01:32
  • It's just how I was formatting the output of a `toString()` method for a List of that object. It does look pretty strange when you see it inside a String inside a JSON. – CorayThan Nov 09 '13 at 01:39

3 Answers3

6

The writeValue() methods of the ObjectWriter class encode the input text.

You don't need to write to a file. An alternative approach for getting the same string could be:

StringWriter sw = new StringWriter();
new ObjectMapper().writer().writeValue(sw, booksMessage);
String result = sw.toString();
PNS
  • 19,295
  • 32
  • 96
  • 143
  • Doing it that way didn't seem to change the result. I think the problem line was actually one I didn't show: `FileUtils.writeStringToFile(tempFile, booksJson, false);` It seems when I wrote it to file `"\""` would become `"""`, while when jackson wrote to the file it would retain the `\` escape character. – CorayThan Nov 09 '13 at 03:13
  • I just pointed out that you can still use the writeValue() method. What you describe in your question is ambiguous in the sense that you seem to expect some quotes to be escaped and others not. If you put together some compilable code (1 method should suffice), with a small input and the expected output, the problem would be easily fixed (if it is fixable). – PNS Nov 09 '13 at 20:12
  • Good stuff, it removed unnecessary escape characters and kept escape characters for quotation marks so JSON compiled fine. Thanks! – Torsten Ojaperv May 13 '15 at 12:58
2

I added

booksJson = Pattern.compile("\\\\").matcher(booksJson).replaceAll("\\\\\\\\");

which escapes all the escape characters. That way when I write it to file and it removes the escapes, I still have the escapes I need. So turns out my real question was how to write to file without Java escapes being removed.

CorayThan
  • 17,174
  • 28
  • 113
  • 161
0

I'm very late to the party but I faced a similar problem and I realized it was not a problem with Jackson or my data. It was Java. I was reading from a JSON file and then trying to write it into a template HTML file.

I had a line my original JSON like yours, something like:

{"field" : "This field contains what looks like another JSON field: {\"abc\": \"value\"}"}

And when I wrote the above to a string, the backslash before the quotes in abc and value disappeared. I noticed that the contextual help for String.replaceAll mentioned something about Matcher.quoteReplacement. I went from this:

template = template.replaceAll("%template%", jsonDataString);

to this:

Pattern pattern = Pattern.compile("%template%");
Matcher matcher = Pattern.matcher(template);
matcher.replaceAll(matcher.quoteReplacement(jsonDataString));

Problem solved.

Matcher.quoteReplacement

dnuttle
  • 3,810
  • 2
  • 19
  • 19