Spring Boot ResponseEntity返回字符串XML数据时响应格式异常
问题产生原因
- Spring Boot接口在返回
application/xml格式响应时,默认使用JAXB作为XML序列化组件。JAXB序列化普通字符串类型的字段时,会默认对字段值中的XML保留字符(包括<、>、换行符、引号等)做实体转义,避免普通文本内容破坏外层XML的结构合法性——这是组件的默认安全机制,不是程序bug。 - 你的代码中通过
response.setData(localResponse)将helperService返回的XML格式字符串,直接赋值给Response对象的String类型data字段。JAXB无法识别这个字段里存的是需要原生嵌入的XML片段,只会按照普通文本规则处理所有特殊字符,最终就出现了你看到的<被转义为<、换行符被转义为
的现象。
可落地的修复方案
- 方案1:使用JAXB原生注解标记XML片段字段(最规范,无结构风险)
调整Response类的data字段定义,将字段类型改为org.w3c.dom.Element,并添加@XmlAnyElement注解,告诉JAXB这个字段存储的是原生XML节点,序列化时直接嵌入不需要转义。
业务代码中先把返回的XML字符串转为Element对象再赋值:
Response类对应字段配置:// 将XML字符串转为DOM元素 DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(new InputSource(new StringReader(localResponse))); Element rawXmlData = doc.getDocumentElement(); Response response = new Response(); response.setStatus("success"); response.setData(rawXmlData); return new ResponseEntity<>(response, HttpStatus.OK);@XmlAnyElement private Element data; - 方案2:自定义XML适配器跳过字符串转义(改动量小)
如果不想修改Response类的字段类型,可以自定义一个JAXB序列化适配器,指定data字段序列化时直接返回原始字符串,不做转义处理。
先定义适配器类:
然后在Response类的data字段上添加注解:public class RawXmlAdapter extends XmlAdapter<String, String> { @Override public String unmarshal(String v) { return v; } @Override public String marshal(String v) { // 直接返回原字符串,不做转义 return v; } }
注意:该方案需要你保证传入data字段的XML字符串本身格式完全合法,没有未闭合标签、特殊字符未处理等问题,否则会导致整个接口返回的XML结构损坏,客户端无法正常解析。@XmlJavaTypeAdapter(RawXmlAdapter.class) private String data; - 方案3:移除XML返回支持(如果业务不需要XML响应)
如果接口没有返回XML格式的业务需求,直接把@GetMapping注解produces属性里的MediaType.APPLICATION_XML_VALUE删除,只保留JSON返回即可。JSON序列化组件不会对字符串中的XML标签做XML实体转义,返回的内容会保留原始格式。
内容的提问来源于stack exchange,提问作者Dattatray Satpute
相关产品推荐
相关产品推荐

