gson 是一个 Google 出品的 JSON 序列化 / 反序列化 Java 库。
序列化
public static <T> String serializeToJson(T object) {
StringWriter writer = new StringWriter();
EscapeNonAsciiWriter escapeWriter = new EscapeNonAsciiWriter(writer);
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
gson.toJson(object, escapeWriter);
return writer.toString();
}
Gson 默认会有所谓 Html Escaping,会把诸如 <
>
'
等符号转义,为的是让 JSON 安全地嵌入在 HTML / XHTML 中(来源)。我认为这不是现阶段 JSON 的常见用法,不需要开启。
Gson 不对 UTF-8 字符转义成 \uxxxx
形式,而是保留它原始的字节。它认为 JSON 的编码格式应该由用户代码去理解。但是在一些不允许使用非 ASCII 字符的场景(比如 HTTP 头中)会不方便。但是 Gson 提供了用户自定义 writer 的能力,因此我们可以写一个 EscapeNonAsciiWriter
解决这个问题:
// 测试过这个类,对中文有效,对处于 Unicode Plane 1 的字符也有效
public class EscapeNonAsciiWriter extends Writer {
private final Writer out;
public EscapeNonAsciiWriter(Writer out) {
this.out = out;
}
@Override
public void write(char[] buffer, int offset, int count) throws IOException {
for (int i = 0; i < count; i++) {
char c = buffer[i + offset];
if (c <= 0x7f) {
out.write(c);
} else {
out.write(String.format("\\u%04x", (int) c));
}
}
}
@Override
public void flush() throws IOException {
out.flush();
}
@Override
public void close() throws IOException {
out.close();
}
}
反序列化
public static SomePojo deserializeFromJson(String buffer) {
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
return gson.fromJson(buffer, SomePojo.class);
}
gson.fromJson
的第二个参数,接受一个 class 对象(如 Metadata.class
),由于 Java 存在 范型擦除(List<String>.class
在字节码上就是 List<>.class
),Gson 提供了 TypeToken
来方便指定类型。但是我不知道怎么用。对 Java 理解深了后看看 这篇文章。