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

如何在Spring中启用WS-Addressing以识别ReplyTo头?

解决Spring Web Services处理WS-Addressing ReplyTo头的问题

核心原因说明

@javax.xml.ws.soap.Addressing是JAX-WS规范的注解,而Spring Web Services(Spring-WS)是独立的框架,并不兼容该注解,所以添加后无法生效。必须使用Spring-WS原生的WS-Addressing处理机制。


1. 启用WS-Addressing支持,解决mustUnderstand报错

通过注册Spring-WS自带的WsAddressingInterceptor拦截器,来处理WS-Addressing头,包括mustUnderstand=true的情况。

方式一:直接注册拦截器Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ws.soap.addressing.server.WsAddressingInterceptor;

@Configuration
public class WebServiceConfig {

    @Bean
    public WsAddressingInterceptor wsAddressingInterceptor() {
        WsAddressingInterceptor interceptor = new WsAddressingInterceptor();
        interceptor.setMustUnderstand(true); // 开启mustUnderstand头处理
        return interceptor;
    }
}

方式二:通过WsConfigurer添加到拦截器链

import org.springframework.context.annotation.Configuration;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.soap.addressing.server.WsAddressingInterceptor;
import java.util.List;

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        interceptors.add(new WsAddressingInterceptor());
        super.addInterceptors(interceptors);
    }
}

2. 实现异步响应(返回202并发送到ReplyTo端点)

要返回202 Accepted并将响应异步发送到ReplyTo指定地址,需要分三步操作:

2.1 提取ReplyTo地址

在@Endpoint方法中,通过MessageContext提取WS-Addressing的ReplyTo端点信息:

import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.addressing.server.AddressingUtils;
import org.springframework.ws.soap.addressing.core.EndpointReference;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.http.HttpStatus;

@Endpoint
public class BusinessEndpoint {

    private final RequestProcessor requestProcessor;

    public BusinessEndpoint(RequestProcessor requestProcessor) {
        this.requestProcessor = requestProcessor;
    }

    @PayloadRoot(namespace = "http://your-custom-namespace.com", localPart = "BusinessRequest")
    public void handleRequest(BusinessRequest request, MessageContext messageContext) {
        // 提取ReplyTo地址
        EndpointReference replyTo = AddressingUtils.getReplyTo(messageContext);
        
        // 异步处理请求并发送响应
        requestProcessor.processAndSendAsync(request, replyTo);
        
        // 设置响应状态为202 Accepted
        messageContext.getResponse().setStatus(HttpStatus.SC_ACCEPTED);
    }
}

2.2 异步处理并发送响应

使用@Async实现异步任务,并通过WebServiceTemplate发送响应到ReplyTo地址:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.addressing.core.EndpointReference;

@Component
public class RequestProcessor {

    private final WebServiceTemplate webServiceTemplate;

    public RequestProcessor(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }

    @Async
    public void processAndSendAsync(BusinessRequest request, EndpointReference replyTo) {
        // 模拟业务处理逻辑(替换为实际业务代码)
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        // 构建响应对象
        BusinessResponse response = new BusinessResponse();
        response.setResult("Request processed successfully");

        // 发送响应到ReplyTo指定地址
        webServiceTemplate.setDefaultUri(replyTo.getAddress().toString());
        webServiceTemplate.marshalSendAndReceive(response);
    }
}

2.3 启用异步支持

在Spring Boot主类上添加@EnableAsync注解,开启异步任务能力:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@SpringBootApplication
public class WebServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebServiceApplication.class, args);
    }
}

3. 依赖确认

确保项目依赖中包含spring-boot-starter-webservices(Spring Boot默认已集成,无需额外添加):

<!-- Maven依赖示例 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webservices</artifactId>
</dependency>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:50:38