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

Java Spring中配置WebServiceServerTest与MockWebServiceClient进行SOAP测试

解决Spring SOAP测试中自定义Endpoint拦截器未生效的替代方案

针对你在Spring SOAP服务测试中遇到的自定义拦截器不生效问题,除了@SpringBootTest + @AutoConfigureMockWebServiceClient的组合,还有以下几种轻量且精准的解决方案:

1. 手动向MockWebServiceClient注册拦截器

@WebServiceServerTest默认不会自动加载完整的拦截器配置,但可以在测试初始化时,手动将自定义拦截器添加到MockWebServiceClient的拦截器链中:

@WebServiceServerTest(YourSoapEndpoint.class)
class SoapEndpointInterceptorTest {

    @Autowired
    private ApplicationContext context;

    @Autowired
    private YourCustomEndpointInterceptor customInterceptor;

    private MockWebServiceClient client;

    @BeforeEach
    void setUp() {
        // 创建客户端时手动注入自定义拦截器
        client = MockWebServiceClient.createClient(context)
                .interceptors(customInterceptor);
    }

    @Test
    void testInterceptorModifiesResponse() {
        // 构造SOAP请求体
        String requestPayload = "<soap:Envelope>...</soap:Envelope>";
        // 预期拦截器修改后的响应体
        String expectedResponse = "<soap:Envelope>...</soap:Envelope>";

        client.sendRequest(withPayload(requestPayload))
                .andExpect(payload(expectedResponse));
        
        // 验证拦截器的交互逻辑,比如检查捕获的请求内容
        assertThat(customInterceptor.getCapturedRequestContent()).isNotBlank();
    }
}

这种方式仅加载必要的Endpoint组件,比全上下文启动更高效,同时确保拦截器参与请求处理流程。

2. 为@WebServiceServerTest指定自定义配置类

创建一个测试专用的Spring配置类,显式注册拦截器到Spring WS的拦截器链中,再通过@WebServiceServerTest加载该配置:

// 测试专用配置类,注册拦截器
@TestConfiguration
static class TestSoapInterceptorConfig implements WsConfigurer {

    @Bean
    public YourCustomEndpointInterceptor customEndpointInterceptor() {
        return new YourCustomEndpointInterceptor();
    }

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

// 指定要测试的Endpoint和自定义配置类
@WebServiceServerTest(
        endpoints = YourSoapEndpoint.class,
        classes = TestSoapInterceptorConfig.class
)
class SoapEndpointTest {

    @Autowired
    private MockWebServiceClient client;

    @Autowired
    private YourCustomEndpointInterceptor customInterceptor;

    @Test
    void testInterceptorBehavior() {
        // 测试逻辑:发送请求,验证拦截器对响应的修改
        client.sendRequest(withPayload("<request>...</request>"))
                .andExpect(payload("<modified-response>...</modified-response>"));
        
        // 验证拦截器的方法是否被调用
        verify(customInterceptor, times(1)).handleRequest(any(), any(), any());
    }
}

该方案既保持了@WebServiceServerTest的轻量性,又能让拦截器通过配置类被Spring WS上下文识别。

3. 基于MockMvc直接配置MessageDispatcherServlet

如果需要更底层的控制,可以手动配置Spring WS的MessageDispatcherServlet,注册拦截器后用MockMvc发送请求:

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {YourSoapEndpoint.class})
class SoapEndpointMockMvcTest {

    private MockMvc mockMvc;

    @Autowired
    private YourCustomEndpointInterceptor customInterceptor;

    @BeforeEach
    void setUp() {
        // 手动配置MessageDispatcherServlet并注册拦截器
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        AnnotationConfigApplicationContext servletContext = new AnnotationConfigApplicationContext();
        servletContext.register(WsTestConfig.class);
        servletContext.refresh();
        servlet.setApplicationContext(servletContext);

        mockMvc = MockMvcBuilders.standaloneSetup(servlet).build();
    }

    // 配置WS基础组件和拦截器
    @TestConfiguration
    static class WsTestConfig implements WsConfigurer {
        @Override
        public void addInterceptors(List<EndpointInterceptor> interceptors) {
            interceptors.add(new YourCustomEndpointInterceptor());
        }

        @Bean
        public DefaultWsdl11Definition defaultWsdl11Definition() {
            DefaultWsdl11Definition wsdlDefinition = new DefaultWsdl11Definition();
            wsdlDefinition.setPortTypeName("YourServicePort");
            wsdlDefinition.setLocationUri("/soap/services");
            // 补充XSD、命名空间等配置
            return wsdlDefinition;
        }
    }

    @Test
    void testSoapRequestWithInterceptor() throws Exception {
        String soapRequest = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">...</soap:Envelope>";

        mockMvc.perform(post("/soap/services")
                        .contentType(MediaType.TEXT_XML)
                        .content(soapRequest))
                .andExpect(status().isOk())
                .andExpect(content().xml("<expected-modified-response>...</expected-modified-response>"));
    }
}

这种方式适合需要完全控制Servlet初始化流程的场景,灵活性极高,但配置相对繁琐。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:53:17