Я пытаюсь создать макет для существующего 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