You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中调用SOAP XML Web Service的最佳方法咨询

基于Spring Boot的SOAP XML Web服务调用最佳方案

结合你已生成JAXB类的情况,推荐以下三种落地方案,按Spring生态适配度排序:

方案一:Spring WebServices(官方集成首选)

Spring WS是Spring生态下的SOAP服务客户端工具,和JAXB天然适配,配置简洁,适合Spring Boot项目。

1. 引入依赖

在pom.xml中添加Spring WS starter及JAXB依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>

2. 配置核心模板与Marshaller

创建配置类,指定JAXB类的包路径(需包含Header和Body对应的生成类):

@Configuration
public class SoapClientConfig {

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // 替换为你生成的JAXB类实际包路径
        marshaller.setContextPaths(
            "com.bi.service.entity.message._2003",
            "com.bi.service.provider.bi.biService.findBIDoc._2003"
        );
        return marshaller;
    }

    @Bean
    public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marshaller) {
        WebServiceTemplate template = new WebServiceTemplate();
        template.setMarshaller(marshaller);
        template.setUnmarshaller(marshaller);
        // 设置目标SOAP服务端点地址
        template.setDefaultUri("http://your-actual-soap-endpoint");
        return template;
    }
}

3. 编写客户端调用逻辑

封装服务调用,手动注入SOAP Header(对应你Postman示例中的BIContext):

@Service
public class BIDocSoapClient {

    private final WebServiceTemplate webServiceTemplate;

    // 构造注入模板
    public BIDocSoapClient(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }

    public FindBIDocResponse invokeFindBIDoc() {
        // 构造请求Body
        FindBIDocRequest request = new FindBIDocRequest();
        request.setVersion(new Version("13"));
        request.setDocNumber("789999");
        request.setUserId("test");
        request.setReadOnly(true);

        // 构造请求Header
        BIContext biContext = new BIContext();
        biContext.setMessageId("89");
        biContext.setCreationTimestamp(OffsetDateTime.parse("2018-07-27T03:56:56.449Z"));
        biContext.setHostName("localhost");

        // 发送请求并注入Header
        return (FindBIDocResponse) webServiceTemplate.marshalSendAndReceive(
            request,
            message -> {
                SoapMessage soapMsg = (SoapMessage) message;
                webServiceTemplate.getMarshaller().marshal(biContext, soapMsg.getSoapHeader().getResult());
            }
        );
    }
}

方案二:Apache CXF(高自定义需求首选)

如果需要拦截器、安全认证等高级自定义功能,Apache CXF是更灵活的选择,Spring Boot集成也很方便。

1. 引入依赖

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    <version>3.6.2</version> <!-- 选择与Spring Boot版本兼容的版本 -->
</dependency>

2. 生成客户端接口(可选)

用CXF的wsdl2java工具生成客户端代码(若已有JAXB类,可跳过直接手动定义接口):

wsdl2java -p com.bi.service.client -d src/main/java your-service.wsdl

3. 配置CXF客户端与Header拦截器

@Configuration
public class CxfClientConfig {

    @Bean
    public FindBIDocService findBIDocService() {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(FindBIDocService.class); // 生成的客户端接口
        factory.setAddress("http://your-actual-soap-endpoint");
        // 添加自定义Header拦截器
        factory.getOutInterceptors().add(new BIContextHeaderInterceptor());
        return (FindBIDocService) factory.create();
    }

    // 自定义SOAP Header拦截器
    private static class BIContextHeaderInterceptor extends AbstractSoapInterceptor {

        public BIContextHeaderInterceptor() {
            super(Phase.PREPARE_SEND);
        }

        @Override
        public void handleMessage(SoapMessage message) throws Fault {
            try {
                BIContext biContext = new BIContext();
                biContext.setMessageId("89");
                biContext.setCreationTimestamp(OffsetDateTime.parse("2018-07-27T03:56:56.449Z"));
                biContext.setHostName("localhost");

                JAXBContext jaxbContext = JAXBContext.newInstance(BIContext.class);
                jaxbContext.createMarshaller().marshal(biContext, message.getHeader().getResult());
            } catch (JAXBException e) {
                throw new Fault(new RuntimeException("Header序列化失败", e));
            }
        }
    }
}

4. 调用服务

@Service
public class BIDocCxfClient {

    private final FindBIDocService findBIDocService;

    public BIDocCxfClient(FindBIDocService findBIDocService) {
        this.findBIDocService = findBIDocService;
    }

    public FindBIDocResponse getBIDoc() {
        FindBIDocRequest request = new FindBIDocRequest();
        request.setVersion(new Version("13"));
        request.setDocNumber("789999");
        request.setUserId("test");
        request.setReadOnly(true);
        return findBIDocService.findBIDoc(request);
    }
}

方案三:原生JAX-WS(无框架依赖)

若不想引入任何第三方框架,可直接使用JDK自带的JAX-WS API,适合简单场景快速验证。

1. 生成客户端代码

用JDK自带的wsimport工具生成客户端:

wsimport -p com.bi.service.client -keep your-service.wsdl

2. 原生调用实现

public class NativeSoapClient {

    public static void main(String[] args) {
        // 初始化服务与端口
        FindBIDocService service = new FindBIDocService();
        FindBIDocPortType port = service.getFindBIDocPort();

        // 设置端点地址
        BindingProvider bindingProvider = (BindingProvider) port;
        bindingProvider.getRequestContext().put(
            BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
            "http://your-actual-soap-endpoint"
        );

        // 构造并注入Header
        try {
            BIContext biContext = new BIContext();
            biContext.setMessageId("89");
            biContext.setCreationTimestamp(OffsetDateTime.parse("2018-07-27T03:56:56.449Z"));
            biContext.setHostName("localhost");

            JAXBContext jaxbContext = JAXBContext.newInstance(BIContext.class);
            Marshaller marshaller = jaxbContext.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(biContext, writer);

            List<Header> headers = new ArrayList<>();
            headers.add(new Header(
                new QName("http://service.bi.com/entity/message/2003/", "BIContext"),
                writer.toString()
            ));
            bindingProvider.getRequestContext().put(JAXWSProperties.HTTP_HEADERS, headers);
        } catch (JAXBException e) {
            e.printStackTrace();
        }

        // 构造请求并调用
        FindBIDocRequest request = new FindBIDocRequest();
        request.setVersion(new Version("13"));
        request.setDocNumber("789999");
        request.setUserId("test");
        request.setReadOnly(true);

        FindBIDocResponse response = port.findBIDoc(request);
        // 处理响应逻辑
    }
}

关键注意事项

  • 确认JAXB类的包路径与Marshaller配置一致,避免序列化失败
  • 替换所有http://your-actual-soap-endpoint为真实的服务地址
  • Header的命名空间必须与Postman示例完全匹配(http://service.bi.com/entity/message/2003/)
  • 日期类型需与生成的JAXB类字段类型匹配(若生成的是XMLGregorianCalendar,需对应转换)

内容的提问来源于stack exchange,提问作者samd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 13:30:01