我使用 Jackson 生成 JSON 对象并将它们直接写入 HTML 的标签中,如下所示:
<script>
var data = $SomeJacksonWrapper.toJson($data);
</script>
如果某个字符串中包含
'</script>'
,此代码就会中断。转义正斜杠 (/) 可以解决该问题,并且 JSON 规范允许这样做。
如何在杰克逊启用它?
使用StaxMan的答案,我最终得到了以下代码:
public class CustomCharacterEscapes extends CharacterEscapes {
private static final Logger log = Logger.getLogger(CustomCharacterEscapes.class);
private final int[] _asciiEscapes;
public CustomCharacterEscapes() {
_asciiEscapes = standardAsciiEscapesForJSON();
_asciiEscapes['/'] = CharacterEscapes.ESCAPE_STANDARD;
}
@Override
public int[] getEscapeCodesForAscii() {
return _asciiEscapes;
}
@Override
public SerializableString getEscapeSequence(int i) {
return null;
}
}
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
this.getJsonFactory().setCharacterEscapes(new CustomCharacterEscapes());
}
}
除了其他建议之外,Jackson 1.8 还具有“字符转义”功能,该功能允许重新定义转义规则。缺乏文档,但基本上你需要实现
CharacterEscapes
(参见http://jackson.codehaus.org/1.8.2/javadoc/org/codehaus/jackson/io/CharacterEscape),向JsonFactory注册(或直接JsonGenerator),然后将根据您想要的任何规则进行转义。在这种情况下,您只需更改“/”的设置即可使用 ESCAPE_STANDARD。
此外,您还可以添加功能请求来添加简单的开/关功能,因为这个特定的事情听起来对其他人也可能有用。但据我所知还没有具体要求。
感谢 StaxMan 和 Infeligo 在这里的回答(干杯),我找到了一种提供转义/匹配(恕我直言,可怕的)WCF DataContractJsonSerializer 日期标准格式的方法:
/Date(1328053610008+1100)/
这需要使用反斜杠对 / 进行转义,从而在整个网络中产生以下结果:
\/Date(1328053610008+1100)\/
以防万一它可能对其他人有帮助,这里是我使用的 CustomCharacterEscapes 代码:
public class CustomCharacterEscapes extends CharacterEscapes {
private final int[] _asciiEscapes;
public CustomCharacterEscapes() {
_asciiEscapes = standardAsciiEscapesForJSON();
_asciiEscapes['/'] = CharacterEscapes.ESCAPE_CUSTOM;
}
@Override
public int[] getEscapeCodesForAscii() {
return _asciiEscapes;
}
@Override
public SerializableString getEscapeSequence(int i) {
if(i == '/'){
return new SerializableString() {
@Override
public String getValue() {
return "\\/";
}
@Override
public int charLength() {
return 2;
}
@Override
public char[] asQuotedChars() {
return new char[]{'\\','/'};
}
@Override
public byte[] asUnquotedUTF8() {
return new byte[]{'\\','/'};
}
@Override
public byte[] asQuotedUTF8() {
return new byte[]{'\\','/'};
}
};
}
else{
return null;
}
}
}
Kotlin 版本的正斜杠自定义字符转义:
/**
* Behaves like PHP json_encode() in that forward slashes are escaped.
*/
private class PhpCompatJsonEncode : CharacterEscapes() {
private val delegate = JsonpCharacterEscapes()
private val escapeForSlash = SerializedString("\\/")
private val asciiEscapes = standardAsciiEscapesForJSON()
init {
asciiEscapes['/'.code] = ESCAPE_CUSTOM
}
override fun getEscapeCodesForAscii(): IntArray {
return asciiEscapes
}
override fun getEscapeSequence(ch: Int): SerializableString? {
return when (ch) {
'/'.code -> escapeForSlash
else -> delegate.getEscapeSequence(ch)
}
}
}
这也可以针对每个编写器进行配置,而不是全局配置,以防仅在特定位置需要:
val writer: ObjectWriter = objectMapper.writer(PhpCompatJsonEncode())
从 Jackson 2.17 开始,您只需启用
JsonWriteFeature.ESCAPE_FORWARD_SLASHES
即可获得所需的结果。
此功能只是最近合并,不确定它是否也被向后移植到<= 2.16 branches, but i guess pull requests are welcome.