带有MTOM和SoapHeaders的Spring WS Server



我正在尝试为现有的SOAP服务构建一个mock。该服务有几个方法,既使用byte[]形式的MTOM上载,又使用SoapHeaders提交其余信息。此外,该服务使用SoapActions来标识端点操作。我无法修改服务。我使用wsdl2java生成API对象

终点:

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

fileHashfileNamefileOptions是标头。在我的Mock中,我不需要所有的。我尝试将它们全部添加到方法的签名中,但没有任何更改。

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的Marshaller。我读到过,为了允许SoapHeaders,还应该使用SoapMethodArgumentResolver,所以我做到了。

我的终结点不能同时使用MTOM和SoapHeader。当我从端点方法中删除SoapHeaders时,端点可以工作,有效负载是正确的,但标头被忽略。当我不重写DefaultMethodEndpointAdapterSoapHeaders时,但MTOM负载为0字节。

当我保持代码原样时,会发生以下情况:

  • SoapMessageDispatcher|端点映射。。。将请求映射到端点。。。(查找终结点(
  • SoapMessageDispatcher|正在测试端点适配器(失败(
  • throws java.lang.IollegalStateException:端点没有适配器

有关于如何解决它的线索吗?

版本

  • spring-boot-starter web服务:2.2.4.RELEASE

我通过添加另一个方法参数解析程序解决了同样的问题。这是的工作解决方案

@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;
}

相关内容

  • 没有找到相关文章

最新更新