Reputation: 792
I have just started using Jackson because of the integration with the Spring Framework and have run into an issue with single quotes in a value. When trying to parse the JSON with jQuery on the page, I get a JavaScript error "SyntaxError: missing ) after argument list"
. I am used to using Gson to serialize my objects and don't run into this issue as Gson will replace the single quote with the Unicode \u0027.
For example;
Java
public final class Person {
private String firstName;
private String lastName;
public Person() {}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
}
JSON
In Jackson
[{"person":{"firstName":"James","lastName":"O'tool"}}]
In Gson
[{"person":{"firstName":"James","lastName":"O\u0027tool"}}]
JavaScript;
// This is where the JavaScript fails with the Jackson serialized object
$.parseJSON('${requestScope.person}');
I have looked for a solution, but am unable to find one. Does anyone know if it is possible to configure Jackson to handle single quotes the same way Gson does?
Thank you for your time.
Upvotes: 11
Views: 7126
Reputation: 1123
@Bergi was trying to say: don't use:
$.parseJSON('${requestScope.person}')
simply use
${requestScope.person}
directly!
Upvotes: 0
Reputation: 116522
The other answer shows one way to do this, and it should work pretty well.
But there is another way to do this as well, which is bit less work, explained at "Forcing escaping of HTML characters in JSON using Jackson"
Upvotes: 7
Reputation: 792
To resolve this issue, I ended up creating a custom String serializer for Jackson. I borrowed some source from Gson.
public class HtmlStringSerializer extends StdSerializer<String> {
protected HtmlStringSerializer() { super(String.class); }
private static final String[] HTML_SAFE_REPLACEMENT_CHARS;
static {
HTML_SAFE_REPLACEMENT_CHARS = new String[128];
for (int i = 0; i <= 0x1f; i++) {
HTML_SAFE_REPLACEMENT_CHARS[i] = String.format("\\u%04x", i);
}
HTML_SAFE_REPLACEMENT_CHARS['"'] = "\\\"";
HTML_SAFE_REPLACEMENT_CHARS['\\'] = "\\\\";
HTML_SAFE_REPLACEMENT_CHARS['\t'] = "\\t";
HTML_SAFE_REPLACEMENT_CHARS['\b'] = "\\b";
HTML_SAFE_REPLACEMENT_CHARS['\n'] = "\\n";
HTML_SAFE_REPLACEMENT_CHARS['\r'] = "\\r";
HTML_SAFE_REPLACEMENT_CHARS['\f'] = "\\f";
HTML_SAFE_REPLACEMENT_CHARS['<'] = "\\u003c";
HTML_SAFE_REPLACEMENT_CHARS['>'] = "\\u003e";
HTML_SAFE_REPLACEMENT_CHARS['&'] = "\\u0026";
HTML_SAFE_REPLACEMENT_CHARS['='] = "\\u003d";
HTML_SAFE_REPLACEMENT_CHARS['\''] = "\\u0027";
}
@Override
public void serialize(String string, JsonGenerator gen, SerializerProvider provider) throws IOException, JsonProcessingException {
int last = 0;
int length = string.length();
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
char c = string.charAt(i);
String replacement;
if (c < 128) {
replacement = HTML_SAFE_REPLACEMENT_CHARS[c];
if (replacement == null) { continue; }
} else if (c == '\u2028') {
replacement = "\\u2028";
} else if (c == '\u2029') {
replacement = "\\u2029";
} else {
continue;
}
if (last < i) {
sb.append(string.substring(last, i));
}
sb.append(replacement);
last = i + 1;
}
if (last < length) {
sb.append(string.substring(last));
}
gen.writeString(sb.toString());
}
}
Upvotes: 2