无法在 Spring 引导中使用带有 Spring-WS 的 SOAP WS,但可以从 SOAPUI 工作



我正在使用Spring Boot来使用从WSDL生成的SOAP WS。我添加了 spring-ws-security,以便我可以将用户/密码作为安全标头传递,如配置所示:

@Configuration
public class ClientConfig {
public static final String SIEBEL_ENDPOINT = "http://...";
@Bean
public CustomerClient customerClient() {
CustomerClient client = new CustomerClient();
client.setDefaultUri(SIEBEL_ENDPOINT);
client.setWebServiceTemplate(webServiceTemplate(marshaller()));
return client;
}
@Bean
public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marshaller) {
WebServiceTemplate template = new WebServiceTemplate(marshaller, marshaller);
template.setDefaultUri(SIEBEL_ENDPOINT);
ClientInterceptor[] interceptors = new ClientInterceptor[] {new LogHttpHeaderClientInterceptor(), wsSecurityInterceptor()};
template.setInterceptors(interceptors);
return template;
}
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.test.dms.gen");
return marshaller;
}
@Bean
public Wss4jSecurityInterceptor wsSecurityInterceptor() {
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions(WSHandlerConstants.USERNAME_TOKEN);
wss4jSecurityInterceptor.setSecurementPasswordType(WSConstants.PW_TEXT);
wss4jSecurityInterceptor.setSecurementUsername("rf_USER");
wss4jSecurityInterceptor.setSecurementPassword("rf_USER");
return wss4jSecurityInterceptor;
}
}

服务呼叫:

public class CustomerClient extends WebServiceGatewaySupport {

public CustomerInfoOutput getCustomerInfo(String vin) {
ObjectFactory request = new ObjectFactory();
final CustomerInfoInput custInfoInput = request.createCustomerInfoInput();
custInfoInput.setVINNumber(vin);

return (CustomerInfoOutput) getWebServiceTemplate().marshalSendAndReceive(ClientConfig.SIEBEL_ENDPOINT, custInfoInput);
}
}

一切都生成得很好,并且记录了以下输出:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
SOAP-ENV:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken-e8f183db-44db-4c0b-90d9-ca57e89225fd">
<wsse:Username>rf_USER</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">rf_USER</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns3:CustomerInfo_Input xmlns:ns2="http://siebel.com/testdashboard"
xmlns:ns3="http://test.com/rf/customerinfo" xmlns:ns4="http://test.com/rf"
xmlns:ns5="http://www.siebel.com/xml/IBM%20test%20Dashboard">
<ns3:VINNumber>123456789</ns3:VINNumber>
</ns3:CustomerInfo_Input>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

当我使用 SOAP UI 发送此请求时,它运行良好。但是当它使用从 WSDL 生成的对象发送时,我遇到了这个错误:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>There is no active Web Service with operation named
'http://test.com/rf/customerinfo:CustomerInfo_Input'.(SBL-EAI-04313)
</faultstring>
<detail>
<siebelf:siebdetail xmlns:siebelf="http://www.siebel.com/ws/fault">
<siebelf:logfilename>EAIObjMgr_enu_0023_24117286.log</siebelf:logfilename>
<siebelf:errorstack>
<siebelf:error>
<siebelf:errorcode>SBL-EAI-04313</siebelf:errorcode>
<siebelf:errorsymbol>IDS_EAI_WS_OP_NOT_FOUND</siebelf:errorsymbol>
<siebelf:errormsg>There is no active Web Service with operation named
'http://test.com/rf/customerinfo:CustomerInfo_Input'.(SBL-EAI-04313)
</siebelf:errormsg>
</siebelf:error>
</siebelf:errorstack>
</siebelf:siebdetail>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

有什么想法吗?

PS:请不要关注URI,因为我更改了它们,但是生成的请求在SOAPUI中工作正常。

在暗示@RanjithR的情况下,我处理如下:

我使用 Wireshark 跟踪了 SOAP 调用,我发现 Spring WS 不包含标头SOAPAction。下面的 SOF 问题讨论了这个问题,以及如何配置它(它会将您发送到 Spring 文档,该文档很好地解释了这件事(。Spring-WS 客户端未设置 SOAPAction 标头

第二件事是,即使我添加了标头,它也会继续告诉我端点未发送。

在我的WSDL中,SOAPAction的定义如下:

<soap:operation soapAction="document/http://test.com/rf/customerinfo:CustomerInfo"></soap:operation>

我的 Spring ws 电话是这样的:

return getWebServiceTemplate().marshalSendAndReceive(ClientConfig.SIEBEL_ENDPOINT,
customerInfoInput,
webServiceMessage -> ((SoapMessage)webServiceMessage).setSoapAction("document/http://ripl.com/rforce/customerinfo:CustomerInfo"));

在Wireshark中,我有:

SOAPAction: "http://ripl.com/rforce/customerinfo:CustomerInfo"

但是当我从 SOAP UI 跟踪相同的调用时,我有: SOAPAction: "document/http://ripl.com/rforce/customerinfo:CustomerInfo">

所以我尝试发送一个字符串文字作为 SOAPAction:

""document/http://ripl.com/rforce/customerinfo:CustomerInfo"";请注意操作周围的"",它适用于:)

也许它可以帮助那些必须与侏罗纪公园系统集成的人......

这篇文章为我指出了正确的方向,为我节省了很多时间。使用上述方法没有为我添加操作标头,但以下方法工作正常:

// add action header
final String ActionHeaderName = "Action";
final String ActionHeaderPrefix = "wsa";
final String ActionHeaderNamespace = "http://www.w3.org/2005/08/addressing";
final String ActionHeaderContent = "http://example/ActionHeader";
var actionName = soapEnvelope.createName(ActionHeaderName, ActionHeaderPrefix, ActionHeaderNamespace);
var actionHeader = soapEnvelope.getHeader().addHeaderElement(actionName);
actionHeader.setTextContent(ActionHeaderContent);

非常感谢@Marouane

相关内容

  • 没有找到相关文章