如何在SpringBoot中添加自定义SOAP Header?附SoapUI请求示例
在Spring Boot中添加自定义SOAP Header(含WS-Addressing)
我之前在项目里处理过一模一样的WS-Addressing Header需求,结合你给出的SoapUI示例,这里给你两种最实用的实现方案,按需选择即可:
方案一:使用WebServiceMessageCallback手动添加(单请求定制)
如果只是个别SOAP请求需要添加这些Header,直接在调用WebServiceTemplate时通过回调手动构建是最直接的方式,代码示例如下:
@Autowired private WebServiceTemplate webServiceTemplate; public Object callSoapService(Object requestPayload) { return webServiceTemplate.marshalSendAndReceive(requestPayload, new WebServiceMessageCallback() { @Override public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException { SoapMessage soapMessage = (SoapMessage) message; SoapHeader soapHeader = soapMessage.getSoapHeader(); // 1. 添加WS-Addressing相关Header元素(命名空间:http://www.w3.org/2005/08/addressing) String addressingNs = "http://www.w3.org/2005/08/addressing"; QName toQName = new QName(addressingNs, "To"); SoapHeaderElement toHeader = soapHeader.addHeaderElement(toQName); toHeader.setText("ws://xxx.com/PP/QM/GPMService/Vx"); QName actionQName = new QName(addressingNs, "Action"); SoapHeaderElement actionHeader = soapHeader.addHeaderElement(actionQName); actionHeader.setText("http://xmldefs.xxx.com/PP/QM/GPMService/Vx/AbcService/GetServiceInfoRequest"); QName messageIdQName = new QName(addressingNs, "MessageID"); SoapHeaderElement messageIdHeader = soapHeader.addHeaderElement(messageIdQName); messageIdHeader.setText("ITEST-2018-04-16-0001"); // 这里可以根据需求动态生成唯一ID // 2. 添加自定义Stage Header(替换成你的完整命名空间) String customNs = "http://xmldefs.xxx.com/Technical/YourFullNamespace"; QName stageQName = new QName(customNs, "Stage"); SoapHeaderElement stageHeader = soapHeader.addHeaderElement(stageQName); stageHeader.setText("TEST"); // 比如TEST/PROD等环境标识 } }); }
这个方式的优点是灵活,你可以针对不同请求设置不同的Header值,比如动态生成唯一的MessageID。
方案二:实现WsInterceptor全局拦截(所有请求自动添加)
如果你的所有SOAP请求都需要携带这些Header,那全局拦截器会更省心,不用每次调用都写回调:
步骤1:自定义拦截器类
public class CustomSoapHeaderInterceptor extends WsInterceptorAdapter { @Override public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException { SoapMessage soapMessage = (SoapMessage) messageContext.getRequest(); SoapHeader soapHeader = soapMessage.getSoapHeader(); // 重复Header构建逻辑,固定值可抽成配置项 String addressingNs = "http://www.w3.org/2005/08/addressing"; // 添加To SoapHeaderElement toHeader = soapHeader.addHeaderElement(new QName(addressingNs, "To")); toHeader.setText("ws://xxx.com/PP/QM/GPMService/Vx"); // 添加Action(若需动态适配接口,可通过messageContext获取请求信息调整) SoapHeaderElement actionHeader = soapHeader.addHeaderElement(new QName(addressingNs, "Action")); actionHeader.setText("http://xmldefs.xxx.com/PP/QM/GPMService/Vx/AbcService/GetServiceInfoRequest"); // 动态生成MessageID SoapHeaderElement messageIdHeader = soapHeader.addHeaderElement(new QName(addressingNs, "MessageID")); messageIdHeader.setText("ITEST-" + LocalDate.now() + "-" + UUID.randomUUID().toString().substring(0, 4)); // 添加自定义Stage String customNs = "http://xmldefs.xxx.com/Technical/YourFullNamespace"; SoapHeaderElement stageHeader = soapHeader.addHeaderElement(new QName(customNs, "Stage")); stageHeader.setText("TEST"); return true; } }
步骤2:注册拦截器到WebServiceTemplate
@Configuration public class SoapClientConfig { @Bean public WebServiceTemplate webServiceTemplate() { WebServiceTemplate template = new WebServiceTemplate(); // 其他基础配置(消息转换器、默认请求URI等)... // 注册自定义拦截器 List<ClientInterceptor> interceptors = new ArrayList<>(); interceptors.add(new CustomSoapHeaderInterceptor()); template.setInterceptors(interceptors.toArray(new ClientInterceptor[0])); return template; } }
配置完成后,所有通过这个WebServiceTemplate发送的SOAP请求都会自动带上指定Header,无需重复编码。
关键注意点
- 命名空间必须和你SoapUI示例中的完全一致,否则服务端可能无法识别Header
- Action字段如果需要适配不同接口,可以在拦截器中通过
messageContext解析请求Payload或接口元数据动态生成 - MessageID建议做动态生成,避免重复,比如结合日期+UUID的方式
内容的提问来源于stack exchange,提问作者du-it
相关产品推荐
相关产品推荐

