简体   繁体   English

带有 MTOM 和 SoapHeaders 的 Spring-WS 服务器

[英]Spring-WS Server with MTOM and SoapHeaders

I am trying to build a mock for an existing SOAP Service.我正在尝试为现有的 SOAP 服务构建一个模拟。 The service has several methods that use both MTOM upload in form of byte[] and use SoapHeaders to submit the rest of the information.该服务有几种方法,使用 MTOM 以byte[]形式上传和使用 SoapHeaders 提交信息的 rest。 Moreover, the service uses SoapActions to identify endpoint actions.此外,该服务使用 SoapActions 来识别端点操作。 I can not modify the service.我无法修改服务。 I generated the API Objects using wsdl2java我使用 wsdl2java 生成了API对象

Endpoint:端点:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
import org.springframework.ws.soap.server.endpoint.annotation.SoapHeader;

@Endpoint
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class RenderJobEndpoint {

...

    @SoapAction(value = NAMESPACE_URI + "CreateJob")
    @ResponsePayload
    public RenderJobInfo createJob(@RequestPayload RenderJobCreateJobData parameters,
        @SoapHeader("{http://www.someservice.com/serviceName/}"}fileName") SoapHeaderElement fileNameElement) {

            String fileName = fileNameElement.getText();    
            return service.doStuff(parameters, fileName);
        }

...
}

XSD file XSD文件

<xs:element name="RenderJobCreateJobData">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="data" type="q3:StreamBody" 
                xmlns:q3="http://schemas.microsoft.com/Message" />
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="fileHash" nillable="true" type="xs:base64Binary" />
<xs:element name="fileName" nillable="true" type="xs:string" />
<xs:element name="fileOptions" nillable="true" type="xs:string" />

fileHash , fileName , fileOptions are headers. fileHashfileNamefileOptions是标题。 In my Mock I do not need all of them.在我的 Mock 中,我不需要所有这些。 I have tried adding them all to the method's signature but it changed nothing.我尝试将它们全部添加到方法的签名中,但没有任何改变。

WebServiceConfig网络服务配置

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurationSupport {

    // ********************************   MTOM   ***********************************************

    @Bean
    @Override
    public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() {
        List<MethodArgumentResolver> argumentResolvers = new ArrayList<>();
        argumentResolvers.add(soapMethodArgumentResolver());
        argumentResolvers.add(methodProcessor());

        List<MethodReturnValueHandler> returnValueHandlers = new ArrayList<>();
        returnValueHandlers.add(methodProcessor());

        DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter();
        adapter.setMethodArgumentResolvers(argumentResolvers);
        adapter.setMethodReturnValueHandlers(returnValueHandlers);


        return adapter;
    }

    @Bean
    public SoapMethodArgumentResolver soapMethodArgumentResolver() {
        return new SoapMethodArgumentResolver();
    }

    @Bean
    public MarshallingPayloadMethodProcessor methodProcessor() {
        return new MarshallingPayloadMethodProcessor(marshaller());
    }


    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setContextPath("com.mockservice.service.apidata");
        jaxb2Marshaller.setMtomEnabled(true);
        jaxb2Marshaller.setProcessExternalEntities(true);

        return jaxb2Marshaller;
    }

    // ********************************   MTOM END  ***********************************************


    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean<>(servlet, "/ws/*");
    }

    @Bean(name = "RenderEngine")
    public Wsdl11Definition wsdl11Definition() {
        SimpleWsdl11Definition simpleWsdl11Definition = new SimpleWsdl11Definition();
        simpleWsdl11Definition.setWsdl(new ClassPathResource("someFile.wsdl"));
        return simpleWsdl11Definition;
    }

    @Bean
    public CommonsXsdSchemaCollection xsdSchemaCollection() {
        return new CommonsXsdSchemaCollection(
                new ClassPathResource("someFile.xsd"));
    }

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

I followed the official Spring docs to allow for MTOM handling and overridden the DefaultMethodEndpointAdapter .我遵循官方 Spring 文档以允许 MTOM 处理并覆盖DefaultMethodEndpointAdapter I passed a Marshaller with MTOM enabled.我通过了一个启用了 MTOM 的 Marshaller。 I've read that in order to allow for SoapHeaders one should also use SoapMethodArgumentResolver , so I did.我已经读过,为了允许 SoapHeaders 一个也应该使用SoapMethodArgumentResolver ,所以我做到了。

My endpoints do not work with both MTOM and SoapHeaders.我的端点不适用于 MTOM 和 SoapHeaders。 When I remove SoapHeaders from the endpoint method, the endpoint works, payload is correct but headers are ignored.当我从端点方法中删除 SoapHeaders 时,端点工作,有效负载正确但标题被忽略。 When I do not override DefaultMethodEndpointAdapter SoapHeaders work, but MTOM payload is 0 bytes.当我不覆盖DefaultMethodEndpointAdapter SoapHeaders 工作时,但 MTOM 有效负载为 0 字节。

When I leave the code as it is, the following happens:当我保留代码原样时,会发生以下情况:

  • SoapMessageDispatcher | SoapMessageDispatcher | Endpoint mapping... maps request to endpoint... (finds an endpoint)端点映射...将请求映射到端点...(找到端点)
  • SoapMessageDispatcher | SoapMessageDispatcher | Testing endpoint adapter (fails)测试端点适配器(失败)
  • throws java.lang.IllegalStateException: No adapter for endpoint抛出 java.lang.IllegalStateException:端点没有适配器

Any clues on how to solve it?关于如何解决它的任何线索?

Versions版本

  • spring-boot-starter-web-services: 2.2.4.RELEASE spring-boot-starter-web-services:2.2.4.RELEASE

I've solved this same issue by adding another Method Argument Resolver.我通过添加另一个方法参数解析器解决了同样的问题。 Here's the working solution这是工作解决方案

@Bean
DefaultMethodEndpointAdapter defaultMethodEndpointAdapter(MarshallingPayloadMethodProcessor methodProcessor) {

        DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter();
        
        List<MethodArgumentResolver> argumentResolvers = new ArrayList<>();
        argumentResolvers.add(soapHeaderElementMethodArgumentResolver());
        argumentResolvers.add(soapMethodArgumentResolver());
        argumentResolvers.add(methodProcessor);
        
        adapter.setMethodArgumentResolvers(argumentResolvers);
        adapter.setMethodReturnValueHandlers(Collections.singletonList(methodProcessor));
        return adapter;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM