Reputation: 138
Jackson Object Mapper with Custom Escaping return wrong output for Strings larger than 2000 char
I am using jackson to escape some special characters(<,>,',") from Data. My input is Map of <Object,Object>
. It is working fine except this special input in which string length is larger than 2000 characters.
Below is Main function where I am using Jackson.
Map<Object,Object> specialMap = new HashMap<>();
specialMap.put("id", "482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863");
String result = null;
ObjectMapper objectMapper = new ObjectMapper();
try {
//Escaping Special Characters
objectMapper.getJsonFactory().setCharacterEscapes(new XMLCharacterEscapes());
result = objectMapper.writeValueAsString(specialMap);
} catch (IOException e) {
e.printStackTrace();
}
Here Result
variable should contain string with escaped values. but for this specific input(specialMap
) It gives sequence of \
and \0
characters which is not expected.
XMLCharacterEscapes class
public class XMLCharacterEscapes extends CharacterEscapes {
private final int[] asciiEscapes;
public XMLCharacterEscapes()
{
// start with set of characters known to require escaping (double-quote, backslash etc)
int[] esc = CharacterEscapes.standardAsciiEscapesForJSON();
// Five chars are predefined in XML and require escaping
esc['<'] = CharacterEscapes.ESCAPE_CUSTOM;
esc['>'] = CharacterEscapes.ESCAPE_CUSTOM;
esc['&'] = CharacterEscapes.ESCAPE_CUSTOM;
esc['\''] = CharacterEscapes.ESCAPE_CUSTOM;
esc['\"'] = CharacterEscapes.ESCAPE_CUSTOM;
asciiEscapes = esc;
}
// this method gets called for character codes 0 - 127
@Override public int[] getEscapeCodesForAscii() {
return asciiEscapes;
}
// and this for others; we don't need anything special here
@Override public SerializableString getEscapeSequence(int ch) {
return new EscapedSerializableString(ch);
}
}
EscapedSerializableString class
public class EscapedSerializableString implements SerializableString {
private final String stringValue;
public EscapedSerializableString(int i) {
stringValue = Character.toString((char) i);
}
@Override
public String getValue() {
return StringEscapeUtils.escapeXml11(stringValue);
}
@Override
public int charLength() {
return stringValue.length();
}
@Override
public char[] asQuotedChars() {
return new char[0];
}
@Override
public byte[] asUnquotedUTF8() {
return new byte[0];
}
@Override
public byte[] asQuotedUTF8() {
return new byte[0];
}
}
Upvotes: 3
Views: 9032
Reputation: 3684
Here is a gist with a working version of your code in a groovy script.
There were a couple of syntax errors in your code, you should also check which version of Jackson you are using. I don't understand which values should be escaped in your input string, so I added a tag to get escaped.
import org.codehaus.jackson.SerializableString
import org.codehaus.jackson.io.CharacterEscapes
/**
* Created by Marc Nuri on 2015-12-23.
*/
@Grab('org.codehaus.jackson:jackson-core-asl:1.9.13')
@Grab('org.codehaus.jackson:jackson-mapper-asl:1.9.13')
@Grab('org.apache.commons:commons-lang3:3.4')
Map<Object,Object> specialMap = new HashMap<>();
specialMap.put("id", "<EscapedTag>482863</EscapedTag>,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863");
String result = null;
org.codehaus.jackson.map.ObjectMapper objectMapper = new org.codehaus.jackson.map.ObjectMapper();
try {
//Escaping Special Characters
objectMapper.getJsonFactory().setCharacterEscapes(new CharacterEscapes() {
private static final int[] esc;
static{
esc = CharacterEscapes.standardAsciiEscapesForJSON();
esc[(int)'<'] = CharacterEscapes.ESCAPE_CUSTOM;
esc[(int)'>'] = CharacterEscapes.ESCAPE_CUSTOM;
esc[(int)'&'] = CharacterEscapes.ESCAPE_CUSTOM;
esc[(int)'\''] = CharacterEscapes.ESCAPE_CUSTOM;
esc[(int)'\"'] = CharacterEscapes.ESCAPE_CUSTOM;
}
@Override
int[] getEscapeCodesForAscii() {
return esc
}
@Override
SerializableString getEscapeSequence(final int i) {
return new SerializableString() {
private final String stringValue = Character.toString((char) i);
@Override
public String getValue() {
return org.apache.commons.lang3.StringEscapeUtils.escapeXml11(stringValue);
}
@Override
public int charLength() {
return stringValue.length();
}
@Override
public char[] asQuotedChars() {
return new char[0];
}
@Override
public byte[] asUnquotedUTF8() {
return new byte[0];
}
@Override
public byte[] asQuotedUTF8() {
return new byte[0];
}
}
}
});
result = objectMapper.writeValueAsString(specialMap);
println result;
} catch (IOException e) {
e.printStackTrace();
}
Here is the script output:
{"id":"<EscapedTag>482863</EscapedTag>,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863,482863"}
Upvotes: 2