2019独角兽企业重金招聘Python工程师标准>>>
今天是用gson工具的时候,发现字符串中的‘=’被替换成了unicode编程格式的‘\u003d’,查看了下gson源码,发现了gson在toString的时候的有如下操作:
private void string(String value) throws IOException {
String[] replacements = htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
out.write("\"");
int last = 0;
int length = value.length();
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
String replacement;
if (c < 128) {
replacement = replacements[c];
if (replacement == null) {
continue;
}
} else if (c == '\u2028') {
replacement = "\\u2028";
} else if (c == '\u2029') {
replacement = "\\u2029";
} else {
continue;
}
if (last < i) {
out.write(value, last, i - last);
}
out.write(replacement);
last = i + 1;
}
if (last < length) {
out.write(value, last, length - last);
}
out.write("\"");
}
其中 HTML_SAFE_REPLACEMENT_CHARS 、REPLACEMENT_CHARS 分别为:
REPLACEMENT_CHARS['"'] = "\\\"";
REPLACEMENT_CHARS['\\'] = "\\\\";
REPLACEMENT_CHARS['\t'] = "\\t";
REPLACEMENT_CHARS['\b'] = "\\b";
REPLACEMENT_CHARS['\n'] = "\\n";
REPLACEMENT_CHARS['\r'] = "\\r";
REPLACEMENT_CHARS['\f'] = "\\f";
HTML_SAFE_REPLACEMENT_CHARS = REPLACEMENT_CHARS.clone();
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";
可见HTML_SAFE_REPLACEMENT_CHARS包含了REPLACEMENT_CHARS。而是使用REPLACEMENT_CHARS还是HTML_SAFE_REPLACEMENT_CHARS的关键在于boolean htmlSafe 的取值。该值是在创建Gson对象的时候传入的。
public Gson() {
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
Collections.>emptyMap(), false, false, DEFAULT_JSON_NON_EXECUTABLE,
true, false, false, LongSerializationPolicy.DEFAULT,
Collections.emptyList());
}
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingPolicy,
final Map> instanceCreators, boolean serializeNulls,
boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
boolean prettyPrinting, boolean serializeSpecialFloatingPointValues,
LongSerializationPolicy longSerializationPolicy,
List typeAdapterFactories) {
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
this.serializeNulls = serializeNulls;
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
this.prettyPrinting = prettyPrinting;
无参的构造函数,会将htmlSafe设置成true,也就是我们通过 Gson gson = new Gson(); 生成的gson对象toString的时候会进行HTML_SAFE_REPLACEMENT_CHARS的字符替换。
带有参数的构造函数,htmlSafe字段只有传入的参数决定。而带有参数的Gson构造函数只由GsonBuilder.create()方法调用。
public Gson create() {
List factories = new ArrayList();
factories.addAll(this.factories);
Collections.reverse(factories);
factories.addAll(this.hierarchyFactories);
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories);
return new Gson(excluder, fieldNamingPolicy, instanceCreators,
serializeNulls, complexMapKeySerialization,
generateNonExecutableJson, escapeHtmlChars, prettyPrinting,
serializeSpecialFloatingPointValues, longSerializationPolicy, factories);
}
可见GsonBuilder对象的escapeHtmlChars属性控制着htmlSafe。而GsonBuilder的escapeHtmlChars的默认值为true。但可以通过GsonBuilder对象的disableHtmlEscaping方法来将escapeHtmlChars置为false,而后在调用create方法生成Gson对象,这样生成的Gson对象在toString的时候就只会替换REPLACEMENT_CHARS数组。
public GsonBuilder disableHtmlEscaping() {
this.escapeHtmlChars = false;
return this;
}
总结:
生成的Gson对象的方法:
①Gson gson = new Gson();
gson.toString(obj);
会对HTML_SAFE_REPLACEMENT_CHARS数组中的字符串进行替换
②GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = builder.create();
gson.toString(obj);
会对HTML_SAFE_REPLACEMENT_CHARS数组中的字符串进行替换
③ GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.disableHtmlEscaping();
Gson gson = builder.create();
gson.toString(obj);
会对REPLACEMENT_CHARS数组中的字符串进行替换