Сервер Spring-WS с MTOM и SoapHeaders - PullRequest
       75

Сервер Spring-WS с MTOM и SoapHeaders

0 голосов
/ 30 апреля 2020

Я пытаюсь создать макет для существующего SOAP Сервиса. У службы есть несколько методов, которые используют как загрузку MTOM в форме byte[], так и SoapHeaders для отправки остальной информации. Кроме того, сервис использует SoapActions для определения действий конечной точки. Я не могу изменить сервис. Я сгенерировал объекты API, используя wsdl2 java

Конечная точка:

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-файл

<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" />

fileHa sh, fileName , fileOptions являются заголовками. В моём макете мне не нужны все из них. Я попытался добавить их все в сигнатуру метода, но он ничего не изменил.

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());
    }
}

Я следовал официальным документам Spring, чтобы разрешить обработку MTOM и переопределить DefaultMethodEndpointAdapter . Я прошел маршаллер с включенным MTOM. Я прочитал , что для использования SoapHeaders нужно также использовать SoapMethodArgumentResolver , так что я это сделал.

Мои конечные точки не работают как с MTOM, так и с SoapHeaders. Когда я удаляю SoapHeaders из метода конечной точки, конечная точка работает, полезная нагрузка верна, но заголовки игнорируются. Когда я не переопределяю DefaultMethodEndpointAdapter SoapHeaders работает, но полезная нагрузка MTOM составляет 0 байтов.

Когда я оставляю код как есть, происходит следующее:

  • SoapMessageDispatcher | Отображение конечной точки ... сопоставляет запрос с конечной точкой ... (находит конечную точку)
  • SoapMessageDispatcher | Тестирование адаптера конечной точки (сбой)
  • throws java .lang.IllegalStateException: Нет адаптера для конечной точки

Есть какие-нибудь подсказки, как его решить?

Версии

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