如何在Spring-WS端点中获取不感知命名空间的Source对象?
方案1:代码层转换SoapBody为无命名空间Source(侵入性最低)
该方案无需修改Spring-WS全局配置,仅在需要调用XSLT的处理方法中新增转换逻辑即可:
- 从
SoapBody获取原始Source后,通过标准JAXP接口解析为DOM文档,解析时主动关闭命名空间感知配置 - 转换后的无命名空间DOM直接作为输入传入现有XSLT模板即可正常执行
示例代码片段:
// 1. 构建忽略命名空间的解析器工厂 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(false); // 核心配置,关闭命名空间感知 DocumentBuilder db = dbf.newDocumentBuilder(); // 2. 解析SoapBody内容为无命名空间DOM Source soapBodySource = soapBody.getPayloadSource(); Document doc = db.parse(((StreamSource) soapBodySource).getInputStream()); // 3. 传入XSLT处理即可得到预期结果 DOMSource xsltInput = new DOMSource(doc);
如果SoapBody返回的是DOMSource而非StreamSource,可先将DOMSource序列化为字节流再走上述解析流程,避免直接复用原有带命名空间感知的DOM对象
方案2:全局配置Spring-WS消息工厂,默认生成无命名空间感知的DOM
如果所有端点处理逻辑都不需要感知命名空间,可以直接替换Spring-WS默认的SOAP消息工厂,让其内部解析XML时直接关闭命名空间感知:
- 自定义
SaajSoapMessageFactory子类,重写创建DocumentBuilderFactory的逻辑,将namespaceAware属性设为false - 把自定义的消息工厂注册到Spring上下文,替换默认实现
自定义消息工厂代码:
public class NamespaceUnawareSaajSoapMessageFactory extends SaajSoapMessageFactory { @Override protected DocumentBuilderFactory createDocumentBuilderFactory() { DocumentBuilderFactory dbf = super.createDocumentBuilderFactory(); dbf.setNamespaceAware(false); return dbf; } }
Spring注册配置:
@Bean public SaajSoapMessageFactory soapMessageFactory() throws SOAPException { return new NamespaceUnawareSaajSoapMessageFactory(MessageFactory.newInstance()); }
配置完成后,所有端点方法注入的SoapBody内部DOM默认无命名空间感知,直接取PayloadSource传入XSLT即可正常运行。
注意事项
- 方案2为全局生效配置,若存在其他依赖命名空间解析的逻辑(比如Spring-WS自带的
@PayloadRoot请求分发),会导致分发失效,该场景优先使用方案1 - 两种方案均不需要修改现有XSLT模板,完全符合需求
内容的提问来源于stack exchange,提问作者fml2
相关产品推荐
相关产品推荐

