如何在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
相关产品推荐
相关产品推荐

