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

Spring WS技术问题:接收MTOM请求,如何返回非MTOM响应?

解决方案:接收MTOM请求并返回纯SOAP响应

问题核心在于你当前共用了一个Jaxb2Marshaller处理请求和响应:开启MTOM时响应会自动生成multipart/xop+xml格式,关闭MTOM则无法解析传入的MTOM请求。要实现需求,需要分别配置两个Marshaller,一个用于解析MTOM请求,另一个用于生成纯SOAP响应。

具体实现步骤

1. 配置两个独立的Jaxb2Marshaller

创建两个Marshaller实例,各自对应请求和响应的处理规则:

  • 开启MTOM的Marshaller:用于解析请求中的二进制附件
  • 关闭MTOM的Marshaller:用于生成纯XML格式的SOAP响应

2. 绑定请求/响应专属处理器

为两个Marshaller创建对应的MarshallingPayloadMethodProcessor,分别绑定到请求参数解析器和响应返回值处理器,实现请求和响应的差异化处理。

修改后的配置类代码

@Configuration
public class MyWebServiceConfig {

    @Value("${config1}")
    private String contextPath;

    @Value("${config2}")
    private String namespace;

    @Value("${config3}")
    private String wsdl;

    @Bean
    ServletRegistrationBean<?> webServicesRegistration(ApplicationContext ctx) {
        MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet();
        messageDispatcherServlet.setApplicationContext(ctx);
        messageDispatcherServlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean<>(messageDispatcherServlet, contextPath, "*.wsdl");
    }

    // 处理MTOM请求的Marshaller(开启MTOM)
    @Bean("requestMarshaller")
    public Jaxb2Marshaller requestMarshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath(namespace);
        marshaller.setMtomEnabled(true);
        return marshaller;
    }

    // 生成纯SOAP响应的Marshaller(关闭MTOM)
    @Bean("responseMarshaller")
    public Jaxb2Marshaller responseMarshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath(namespace);
        marshaller.setMtomEnabled(false);
        return marshaller;
    }

    // 请求处理器:绑定开启MTOM的Marshaller
    @Bean
    public MarshallingPayloadMethodProcessor requestProcessor(@Qualifier("requestMarshaller") Jaxb2Marshaller marshaller) {
        return new MarshallingPayloadMethodProcessor(marshaller);
    }

    // 响应处理器:绑定关闭MTOM的Marshaller
    @Bean
    public MarshallingPayloadMethodProcessor responseProcessor(@Qualifier("responseMarshaller") Jaxb2Marshaller marshaller) {
        return new MarshallingPayloadMethodProcessor(marshaller);
    }

    @Bean
    DefaultMethodEndpointAdapter endpointAdapter(MarshallingPayloadMethodProcessor requestProcessor, 
                                                MarshallingPayloadMethodProcessor responseProcessor) {
        DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter();
        // 参数解析使用请求处理器,解析MTOM请求
        adapter.setMethodArgumentResolvers(Collections.singletonList(requestProcessor));
        // 返回值处理使用响应处理器,生成纯SOAP响应
        adapter.setMethodReturnValueHandlers(Collections.singletonList(responseProcessor));
        return adapter;
    }

    @Bean
    public SimpleWsdl11Definition contentStore() {
        SimpleWsdl11Definition definition = new SimpleWsdl11Definition();
        definition.setWsdl(new ClassPathResource(wsdl));
        return definition;
    }
}

端点代码无需修改

你的端点业务逻辑保持原样即可,请求解析和响应生成的差异化逻辑已由配置中的处理器完成:

@Endpoint
public class MyEndpoint {

    private ObjectFactory objectFactory;

    public MyEndpoint() {
        this.objectFactory = new ObjectFactory();
    }
    
    @PayloadRoot(localPart = "SendMyRequest", namespace = "somenamespace")
    @ResponsePayload
    public JAXBElement<MyReceipt> store(@RequestPayload JAXBElement<MyRequest> storeContentRequest) throws IOException {
        MyReceipt receipt = new MyReceipt();
        receipt.setf1(123);
        receipt.setf2(456);
        return this.objectFactory.createMyResponse(receipt);
    }
}

原理说明

  • 请求阶段:requestMarshaller开启MTOM,能够正确解析multipart/related格式的MTOM请求,提取二进制附件并绑定到JAXB对象
  • 响应阶段:responseMarshaller关闭MTOM,将JAXB对象序列化为纯XML格式的SOAP响应,响应的Content-Type会变为text/xml或application/soap+xml,不再是multipart类型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:35:17