Java使用JAXBMarshaller转XML如何避免字符串特殊字符自动转义
解决方案
因为你无法调整JAXBContext和Marshaller的创建逻辑,无法通过修改Marshaller的转义处理器属性关闭转义,可通过以下两种仅修改业务对象的方式实现需求:
方法1:使用@XmlAnyElement注解直接输出原始内容
JAXB处理@XmlAnyElement标注的DOM Element类型字段时,会直接输出节点的原始内容,不会做额外转义。操作步骤如下:
- 修改业务对象中需要保留原始字符的字段类型,从
String改为org.w3c.dom.Element,添加@XmlAnyElement注解 - 新增字段的setter方法,接收字符串参数,自动转换为DOM Element对象
示例代码:
import org.w3c.dom.Element; import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; @XmlRootElement(name = "example") public class ExampleObj { private Element content; @XmlAnyElement public Element getContent() { return content; } public void setContent(String rawContent) throws Exception { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); // 直接创建包含原始内容的文本节点 this.content = doc.createElement("content"); this.content.appendChild(doc.createTextNode(rawContent)); } }
输出效果:假设传入This is a "Test" <>,最终输出为<content>This is a "Test" <></content>,不会出现二次转义的&quot;。
方法2:使用XmlAdapter适配字符串输出
自定义XmlAdapter将字符串转换为JAXB可识别的不转义节点,同样不需要修改Marshaller配置:
- 自定义继承自
XmlAdapter<Element, String>的适配器类 - 在需要取消转义的字符串字段上添加
@XmlJavaTypeAdapter注解,指定自定义适配器
示例代码:
import javax.xml.bind.annotation.adapters.XmlAdapter; import org.w3c.dom.Element; import org.w3c.dom.Document; import javax.xml.parsers.DocumentBuilderFactory; public class NoEscapeXmlAdapter extends XmlAdapter<Element, String> { @Override public String unmarshal(Element v) throws Exception { return v.getTextContent(); } @Override public Element marshal(String v) throws Exception { Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element element = doc.createElement("content"); element.appendChild(doc.createTextNode(v)); return element; } }
业务对象使用方式:
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement(name = "example") public class ExampleObj { private String content; @XmlJavaTypeAdapter(NoEscapeXmlAdapter.class) public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
注意事项
- 两种方式都不需要修改XSD文件,仅修改业务对象代码即可
- 输出前请确认原始字符串的格式合法性,避免生成无效XML
内容的提问来源于stack exchange,提问作者RandomUser0999
相关产品推荐
相关产品推荐

