6

I'm facing issues while parsing JSON strings with Jackson in some cases.

String jsonString = "{\"Age\":40, \"Name\":\"Sample User\"}";
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(jsonString,JsonNode.class);

System.out.println(jsonstirng)
{"Age":40, "Name":"Sample User"}

The above code works well when I pass the jsonString value.

In some cases, I need to escape invalid string characters like ",' etc

For escaping I am using Apache StringEscapeUtils.

String escapedString = StringEscapeUtils.escapeJson(jsonStirng);

Escaped String output

{\"Age\":40,\"Name\":\"Sample User\"}

When I pass the escaped string to mapper its throws an Unexpected character exception.

ObjectMapper mapper = new ObjectMapper();
mapper.readValue(escapedString,JsonNode.class);

Exception

Unexpected character ('\' (code 92)): was expecting double-quote to start field name

Actually, I'm parsing ModSecurity audit logs. The response body of the audit log has (HTML, CSS, javascript, etc) stuff that's why I need to escape the JSON string other wise its breaks the JSON format.

basit raza
  • 661
  • 2
  • 6
  • 18
  • Why are you escaping the quotes in that string? The real Json string should not have escapes in it. Print the `jsonString` you have in your first line and you'll see that internally it doesn't have any escaping. – RealSkeptic Apr 15 '16 at 12:13
  • The question has very confusing description, it is not even compilable and escaping magically changes Age from 40 to 33. Please check and show real code. But I could only assume that you are quoting something wrong. – kan Apr 15 '16 at 12:15
  • @kan typo mistake. Now am update it kindly have a look. – basit raza Apr 15 '16 at 12:50
  • You should not escape json string itself, you only need to escape raw strings which will be placed as values of a json formatted document. – kan Apr 15 '16 at 13:47
  • According to your last line in the question, you need to escape the "stuff", but not a JSON. – kan Apr 15 '16 at 13:56
  • @kan but that stuff is part of json. – basit raza Apr 15 '16 at 15:27
  • @basitraza It could not be part of a json if it is not escaped already. Show your stuff so we could see what you actually have and want to do. The `jsonString` in your current example is already escaped as it should, no need to touch it. – kan Apr 15 '16 at 15:37

1 Answers1

5

The purpose of escaping a String is to make it unparsable as piece of JSON.

In your cause you are replacing all the " with \" so that it can be used inside a String value and the parser will NOT see it as part of the JSON.

e.g. this is just one field and value;

"myJson": "{\"Age\":40,\"Name\":\"Sample User\"}"

what you can't do is the following which is why you need this method. It can't tell the difference between " which starts/ends the string and the " inside the string.

"myJson": "{"Age":40,"Name":"Sample User"}"

If you then try to parse this escaped String, it shouldn't be able to parse it.


EDIT: Here is an example

String text = "{\"Age\":40,\"Name\":\"Sample User\"}";
String escaped = StringEscapeUtils.escapeJson(text);
System.out.println("escaped= " + escaped);
String unescaped = StringEscapeUtils.unescapeJson(escaped);
System.out.println("unescaped= " + unescaped);

prints

escaped= {\"Age\":40,\"Name\":\"Sample User\"}
unescaped= {"Age":40,"Name":"Sample User"}

you can see that the escaped string has \" however the unescaped string doesn't. If you are still seeing \ I would assume the String hasn't been unescaped.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Actually Am parsing ModSecurity audit logs with jackson. Am also getting response header and response body. Response body has (html,css,javascript etc) stuff that's why I need to escape json string other wise its breaks the json format. – basit raza Apr 15 '16 at 12:38
  • @basitraza agreed, escaping is for safely placing a String inside a value. To parse such a string, you have to unescape it first to reverse what it does. Note: there is more than one way to escape out a string, so it's best to use a matching unescape – Peter Lawrey Apr 15 '16 at 12:42
  • what you recommend in this scenario. Am tried different escaping pattern but nothing changed. Escaping single quote ` ' ` works in some cases but not in all. – basit raza Apr 15 '16 at 13:00
  • @basitraza You should be able to call escape on a String and use it as a value, when extracting the value you have to call unescape. Which character did this not work on? – Peter Lawrey Apr 15 '16 at 13:05
  • I did unescaping before parsing but jackson object mapper throw Unexpected character exception, Actually its already broken json string due to invalid characters – basit raza Apr 15 '16 at 13:26
  • @basitraza I have added an example. – Peter Lawrey Apr 15 '16 at 13:37
  • ` String jsonString = "{\"Age\":40, \"Name\":\"Sample '\" User\"}"; StringEscapeUtils.unescapeJson(jsonString); ` – basit raza Apr 15 '16 at 13:40
  • unescaping works in case of valid json string, but not works if invalid character in json string – basit raza Apr 15 '16 at 13:43
  • @basitraza if you escaped the string correctly, there shouldn't be any invalid characters for the contents of a value. This is the purpose of escaping the String. – Peter Lawrey Apr 15 '16 at 13:45
  • thanks for you help. Is regex is good approach for un-escaping – basit raza Apr 15 '16 at 15:25
  • @basitraza I would use the `unescapeJson` as I suggested. If you don't know how it was escaped, you need to understand what the mapping is and then work out a solution. – Peter Lawrey Apr 15 '16 at 15:30
  • @basitraza Using regex for json is very similar as for html, so just read instructions here: http://stackoverflow.com/a/1732454/438742 – kan Apr 15 '16 at 15:46