Java中使用Gson解析含特殊字符(如&)失败,如何保留原数值?
解决Gson反序列化特殊字符的坑
嘿,我来帮你搞定这两个Gson反序列化的问题!你遇到的情况其实都是Gson默认行为的锅,咱们一步步拆解解决:
1. 解析'、&这类HTML实体字符
Gson默认不会自动解码HTML实体,所以遇到'(对应单引号')、&(对应&)这类字符时,它会直接把它们当成普通字符串处理,不会转成原始字符。解决办法是给String类型加个自定义的TypeAdapter,让它在反序列化时自动解码这些实体:
方案一:用第三方库快速实现
比如用Apache Commons Text的StringEscapeUtils来做解码,省得自己写一堆替换逻辑:
import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import java.io.IOException; import org.apache.commons.text.StringEscapeUtils; public class HtmlEntityDecoderAdapter extends TypeAdapter<String> { @Override public void write(JsonWriter out, String value) throws IOException { // 序列化时保持原样,不需要额外处理 out.value(value); } @Override public String read(JsonReader in) throws IOException { String rawValue = in.nextString(); // 解码所有HTML实体 return StringEscapeUtils.unescapeHtml4(rawValue); } }
然后创建Gson实例的时候注册这个适配器就行:
Gson gson = new GsonBuilder() .registerTypeAdapter(String.class, new HtmlEntityDecoderAdapter()) .create();
方案二:自己实现简单的实体替换
如果不想引入第三方库,也可以手动替换常见的HTML实体:
private String decodeHtmlEntities(String rawValue) { return rawValue.replace("&", "&") .replace("'", "'") .replace(""", "\"") .replace("<", "<") .replace(">", ">"); }
把这个方法放到上面的TypeAdapter的read方法里替换掉StringEscapeUtils的调用就好。
2. 确保&这类特殊字符和原始值完全一致
这个问题分两种情况:
- 如果你的原始JSON里的
&是被转义成\&(也就是JSON字符串里写的是"a\\&b"),Gson默认会正确解析成a&b,这时候不用额外处理。 - 如果是传输过程中(比如后端返回时)把
&转成了&,那还是得用上面的HTML实体解码方案,把它转回到原始的&。
另外,如果是序列化时出现&被转义的问题(比如你把POJO转成JSON时,&变成了\u0026或者&),可以创建Gson时关闭HTML转义:
Gson gson = new GsonBuilder() .disableHtmlEscaping() .create();
这样序列化出来的字符串会保留原始的&,不会被转义。
额外提醒
- 先确认你的原始JSON数据是否正确:比如后端返回的JSON里到底是原始的
&还是转义后的&,这决定了你需要用哪种处理方式。 - 如果你用Retrofit这类框架,要确保ConverterFactory没有额外做字符串处理,避免重复转义/解码导致的问题。
内容的提问来源于stack exchange,提问作者Abdeali Chandanwala
相关产品推荐
相关产品推荐

