如何避免Apache Camel调用.marshal().jacksonxml()时&被错误转义
Apache Camel JacksonXML 序列化符号转义问题解决方案
方案1:自定义Jackson XmlMapper转义规则(推荐)
通过修改Jackson XML序列化的底层字符转义配置,仅取消原生&的转义规则,原有&内容不会被二次转义,符合需求:
import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; import com.fasterxml.jackson.core.io.CharacterEscapes; import org.apache.camel.dataformat.jacksonxml.JacksonXMLDataFormat; // 初始化自定义XmlMapper XmlMapper customXmlMapper = XmlMapper.builder() // 对应你原有代码的false参数,关闭XML声明输出 .configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, false) .build(); // 自定义字符转义规则,取消&的默认转义 customXmlMapper.getFactory().setCharacterEscapes(new CharacterEscapes() { private final int[] asciiEscapes = CharacterEscapes.standardAsciiEscapesForJSON(); { // 仅将&的转义规则设为不转义 asciiEscapes['&'] = ESCAPE_NONE; } @Override public int[] getEscapeCodesForAscii() { return asciiEscapes; } @Override public java.io.SerializableString getEscapeSequence(int ch) { // 非ASCII字符沿用默认转义规则 return null; } }); // 在Camel路由中替换原有marshal配置 JacksonXMLDataFormat customXmlFormat = new JacksonXMLDataFormat(customXmlMapper); // 路由写法示例: from("yourEndpoint") .marshal(customXmlFormat) .to("nextEndpoint");
方案2:临时标记替换法(兼容性更高)
如果不想修改Jackson底层配置,可通过预处理+后处理的方式区分两类&内容,不会误改原有&:
from("yourEndpoint") // 序列化前预处理:将原生&替换为业务中不存在的唯一临时标记 .process(exchange -> { YourDataPO data = exchange.getIn().getBody(YourDataPO.class); // 遍历所有需要处理的字段做替换 data.setContent(data.getContent().replace("&", "__UNIQUE_AMP_MARKER__")); exchange.getIn().setBody(data); }) // 正常执行XML序列化 .marshal().jacksonxml(false) // 序列化后处理:将临时标记替换回& .process(exchange -> { String xmlContent = exchange.getIn().getBody(String.class); xmlContent = xmlContent.replace("__UNIQUE_AMP_MARKER__", "&"); exchange.getIn().setBody(xmlContent); }) .to("nextEndpoint");
注意事项
- 方案1会保留
<、>、"等其他XML特殊字符的默认转义规则,不会生成非法XML文档 - 方案2的临时标记需要选择业务数据中绝对不会出现的字符串,避免误替换
内容的提问来源于stack exchange,提问作者jay
相关产品推荐
相关产品推荐

