java - 在 SpringBoot 客户端中使用 WebServiceTemplate 调用 SOAP Web 服务
问题描述
我正在使用 WebServiceTemplate 调用 SOAP Web 服务。我可以使用带有以下输入的 SOAP UI 调用服务并获得正确的响应。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:abc="http://abc.hs.com/">
<soapenv:Header>
<version>1<version>
</soapenv:Header>
<soapenv:Body>
<abc:getUser>
<userId>pan</userId>
</abc:getUser>
</soapenv:Body>
</soapenv:Envelope>
但是当使用 WebserviceTemplate 调用时,如下所示:
public String getUser(String userId) {
List<String> detail = new ArrayList<String>();
try {
template = new WebServiceTemplate(marshaller);
String requestPayload = getXmlInput();// This is same xml I am sending using SOAPUI
StreamSource source = new StreamSource(new StringReader(requestPayload));
StreamResult result = new StreamResult(System.out);
template.sendSourceAndReceiveToResult("http://localhost:8080/HERSvc/InsService", source,
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException {
TransportContext context = TransportContextHolder.getTransportContext();
HttpUrlConnection connection = (HttpUrlConnection) context.getConnection();
connection.addRequestHeader("Content-Type", "text/xml; charset=utf-8");
connection.addRequestHeader("soapAction", "");
}
},result);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
我在服务器端收到以下错误:E org.apache.axis2.engine.AxisEngine receive The endpoint reference (EPR) for the Operation not found is http://localhost:8080/HERSvc/InsService and the WSA Action = . If this EPR was previously reachable, please contact the server administrator.
客户端错误消息:出现意外错误(类型=内部服务器错误,状态=500)。
经过https://stackoverflow.com/questions/5981379/the-endpoint-reference-epr-for-the-operation-not-found-is
我在标题中添加了 Content-Type 和 soapAction
注意:我怀疑问题出在我的 requestPayload 没有正确形成。它与 SOAP UI 中使用的字符串相同。似乎输入被转换为 Body
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<soapenv:Envelope xmlns:abc="http://abc.hs.com/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<version>1<version>
</soapenv:Header>
<soapenv:Body>
<abc:getUser>
<userId>pan</userId>
</abc:getUser>
</soapenv:Body>
</soapenv:Envelope>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
解决方案
问题是所需的 Header 没有正确形成。最初我无法创建 objectPayload,因此无法使用 marshalSendAndReceive。因此,为了创建正确的 objectPayload,我使用我的 wsdl 从命令提示符生成 ObjectFactory,然后将创建的所有对象导入到项目中。使用 marshalSendAndReceive 如下
wsimport -d generated http://example.org/stock?wsdl
public User getUser(User user) {
try {
template = new WebServiceTemplate(marshaller);
JAXBElement<?> response = (JAXBElement<?>)template.marshalSendAndReceive("http://localhost:8080/HERSvc/InsService",
new ObjectFactory().createGetUser(user),
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
try {
SoapMessage soapMessage = (SoapMessage)message;
SoapHeader header = soapMessage.getSoapHeader();
StringSource headerSource = new StringSource("<version>1.0</version>");
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(headerSource, header.getResult());
} catch (Exception e) {
e.printStackTrace();
}
}
}) ;
} catch (IOException e) {
e.printStackTrace();
}
GetUserResponse responseObject = (GetUserResponse)response.getValue();
User user = responseObject.getReturn();
}
推荐阅读
- c++ - 如何让 MSVS 识别 bigobj 标志?
- azure - 如何用几个单词自动完成
- c# - Entity Framework Fluent API - 映射多对多关系,并从中查询
- python - 我已将 3 通道 RGB 图像转换为 2 通道灰度图像,如何将灰度通道减少到 1?
- docker-compose - 如何在 docker-compose 中将绝对主机路径挂载为命名卷?
- .net - .net 核心应用程序 SignInAsync 从不同域失败
- node.js - 如何在 Node Express 中使用具有基本 href 的索引来提供静态文件?
- swiftui - Xcode 11 -- SwiftUI 的暗模式设置
- android - 如何使用 dagger2 限制 ViewModelFactory 的范围?
- python - 如何将一个数据框的列值附加到另一个数据框的列