很不幸,Gson似乎不支持此功能。所有JSON输入/输出都集中在Gson中(从2.8.0开始)的JsonReader
和JsonWriter
中。 JsonReader
可以使用其私有的readEscapeCharacter
方法读取Unicode转义。然而,与JsonReader
不同,JsonWriter
仅将字符串写入备份Writer
实例,对于大于127的字符不进行任何字符校正,除了\u2028
和\u2029
。这里唯一能做的事情可能是编写一个自定义的转义Writer
,以便您可以发出Unicode转义。
final class EscapedWriter
extends Writer {
private static final char[] hex = {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f'
};
private final Writer writer;
private final char[] escape = { '\\', 'u', 0, 0, 0, 0 };
EscapedWriter(final Writer writer) {
this.writer = writer;
}
@Override
public void write(final char[] buffer, final int offset, final int length)
throws IOException {
for ( int i = offset; i < length; i++ ) {
final int ch = buffer[i];
if ( ch < 128 ) {
writer.write(ch);
} else {
escape[2] = hex[(ch & 0xF000) >> 12];
escape[3] = hex[(ch & 0x0F00) >> 8];
escape[4] = hex[(ch & 0x00F0) >> 4];
escape[5] = hex[ch & 0x000F];
writer.write(escape);
}
}
}
@Override
public void flush()
throws IOException {
writer.flush();
}
@Override
public void close()
throws IOException {
writer.close();
}
@Override
public String toString() {
return writer.toString();
}
}
这个编写者没有经过充分测试,也不支持
\u2028
和
\u2029
。在调用
toJson
方法时只需配置输出目标即可:
final String input = "{\"description\":\"Tikrovi\\u0161kai para\\u0161ytas k\\u016brinys\"}";
final Book book = gson.fromJson(input, Book.class);
final Writer output = new EscapedWriter(new StringWriter());
gson.toJson(book, output);
System.out.println(input);
System.out.println(output);
输出:
{"description":"Tikroviškai parašytas kūrinys"}
{"description":"Tikroviškai parašytas kūrinys"}
这是一个有趣的问题,您可能还可以在google/gson上提出一个字符串写入配置选项的问题 - 或者至少从开发团队那里得到一些评论。我相信他们非常清楚这样的行为,并通过设计使其正常工作,但他们也可以解释一下(我现在能想到的唯一一个是,目前他们有一些性能,不需要在写入字符串之前进行额外的转换,但这只是一个猜测)。