[英]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. fileHash 、 fileName 、 fileOptions是标题。 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:当我保留代码原样时,会发生以下情况:
Any clues on how to solve it?关于如何解决它的任何线索?
Versions版本
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.