如何使用Jackson XML处理字符?序列化反序列化报错处理
解决Jackson XML序列化/反序列化\uFFFF字符的异常问题
问题原因
XML规范中,属于无效字符实体(XML仅允许U+0009、U+000A、U+000D,以及U+0020到U+D7FF、U+E000到U+FFFD范围内的字符)。Jackson序列化时会将\uFFFF转成输出,但反序列化时XML解析器不认可该实体,直接抛出异常。
解决方案:序列化时过滤无效字符
要实现直接删除不支持的字符、输出纯字符串XML的需求,可通过自定义String序列化器,在序列化前清理掉XML不允许的字符。
步骤1:编写自定义字符串序列化器
该序列化器会过滤掉所有XML规范外的字符:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import java.io.IOException; import java.util.regex.Pattern; public class XmlSafeStringSerializer extends StdSerializer<String> { // 匹配XML 1.0不允许的字符 private static final Pattern INVALID_XML_CHARS = Pattern.compile("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD]"); public XmlSafeStringSerializer() { super(String.class); } @Override public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException { if (value == null) { gen.writeNull(); return; } // 替换无效字符为空字符串 String cleanedContent = INVALID_XML_CHARS.matcher(value).replaceAll(""); gen.writeString(cleanedContent); } }
步骤2:配置XmlMapper使用自定义序列化器
将序列化器注册到XmlMapper中,全局生效:
import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.dataformat.xml.XmlMapper; public class Main { public static void main(String[] args) throws Exception { XmlMapper xmlMapper = new XmlMapper(); SimpleModule xmlSafeModule = new SimpleModule(); xmlSafeModule.addSerializer(String.class, new XmlSafeStringSerializer()); xmlMapper.registerModule(xmlSafeModule); // 测试序列化 String input = "Some valid string but containing the \uFFFF character"; String xmlString = xmlMapper.writeValueAsString(input); System.out.println(xmlString); // 输出:<String>Some valid string but containing the character</String> // 测试反序列化 String deserialized = xmlMapper.readValue(xmlString, String.class); System.out.println(deserialized); // 输出:Some valid string but containing the character } }
效果说明
- 序列化阶段直接移除
\uFFFF这类无效字符,输出的XML完全符合规范,不存在非法实体。 - 反序列化时不会再抛出异常,且输出内容符合需求(无需保留无效字符)。
内容的提问来源于stack exchange,提问作者Gaël J
相关产品推荐
相关产品推荐

