gpt4 book ai didi

java - 如何用 Java 为该 WS 创建 SOAP 请求信封?

转载 作者:太空宇宙 更新时间:2023-11-04 15:23:40 25 4
gpt4 key购买 nike

我对 Java 中的 SOAP WebService 开发非常陌生,并且遇到以下问题。

我有一个公开 2 个方法的 Web 服务,第一个(更简单)已经实现(由其他人)并名为 getVersion(),并且在 SoapUI 中有以下请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:getVersion/>
</soapenv:Body>
</soapenv:Envelope>

然后我有一个 Java 项目,它执行对 Web 服务的调用,并且在一个类中,我为之前的 Web 服务方法提供了以下方法:

公共(public)字符串 getVersion() { java.net.URL url = null; java.net.URLConnection conn = null;

java.io.BufferedReader rd = null;
String soapResponse = "";

String risultato = "";

// SOAP ENVELOP for the request:
String soapRequest;
soapRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" + "<soapenv:Header/>" + "<soapenv:Body> " + "<tem:getVersion/>" + "</soapenv:Body>" + "</soapenv:Envelope>";

try {

// Try to open a connection
url = new java.net.URL(_webServiceUrl);
conn = url.openConnection();

// Set the necessary header fields
conn.setRequestProperty("SOAPAction", "http://tempuri.org/IMyService/getVersion");
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setDoOutput(true);

// Send the request:
java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(conn.getOutputStream());
wr.write(soapRequest);
wr.flush();
// Read the response
rd = new java.io.BufferedReader(new java.io.InputStreamReader(conn.getInputStream()));

// Put the entire response into the soapResponse variable:
String line;
while ((line = rd.readLine()) != null) {
//System.out.println(line);
soapResponse = soapResponse + line + System.getProperty("line.separator");
}

rd.close();

// elaboro la risposta
SAXBuilder builder = new SAXBuilder();

org.jdom.Document documentXML = null;
documentXML = builder.build(new StringReader(soapResponse));

XPath xPath;
Element objectElement;
//xPath = XPath.newInstance("s:Envelope/s:Body/getVersionResponse/getVersionResult");
xPath = XPath.newInstance("s:Envelope/s:Body");
xPath.addNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");

objectElement = (Element) xPath.selectSingleNode(documentXML);

if (objectElement != null) {
risultato = objectElement.getValue();
}

} catch (Exception ex) {
ex.printStackTrace();
}

return risultato;

}

现在我必须复制同样的事情,为第二个方法创建一个新方法(在调用 ws 方法的 Java 项目中)(这更复杂,因为与前一个方法不同,需要传递一些参数)并且我对此有一些疑问。

所以情况如下:在SoapUI中有一个名为getConfigSettings的WS方法,它的请求是:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:getConfigSettings>
<!--Optional:-->
<tem:login>?</tem:login>
<!--Optional:-->
<tem:password>?</tem:password>
<!--Optional:-->
<tem:ipAddress>?</tem:ipAddress>
<!--Optional:-->
<tem:clientVersion>?</tem:clientVersion>
<!--Optional:-->
<tem:lastUpdateTime>?</tem:lastUpdateTime>
</tem:getConfigSettings>
</soapenv:Body>
</soapenv:Envelope>

As you can see it requires some parameters (in SoapUi I have to replace characters with the correct parameter value)

因此,在 Java 项目中,我创建了以下方法来执行此调用,为我的请求创建 SOAP 信封(但我对其正确性有很多疑问)

    public String authentication(String login, String password, String ipAddress, String clientVersion) {


java.net.URL url = null;
java.net.URLConnection conn = null;

java.io.BufferedReader rd = null;
String myResponse = "";
String soapXml;

// SOAP ENVELOP for the request:
//soapXml = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"> " + "<s:Header>" + "<Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">http://tempuri.org/IMyService/getVersion</Action>" + "</s:Header>" + "<s:Body>" + "<getVersion xmlns=\"http://tempuri.org/\" />" + "</s:Body>" + "</s:Envelope>";
soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">"
+ "<soapenv:Header/>"
+ "<soapenv:Body> "
+ "<tem:login>" + login + "</tem:login>"
+ "<tem:password>" + password + "</tem:password>"
+ "<tem:ipAddress>" + ipAddress + "</tem:ipAddress>"
+ "</soapenv:Body>"
+ "</soapenv:Envelope>";
........................................................
........................................................
........................................................
DO SOME OTHER STUFF
........................................................
........................................................
........................................................
}

如您所见,我为我的请求创建了这个 SOAP 信封,其中插入了作为方法的输入参数接收的参数:

    soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" 
+ "<soapenv:Header/>"
+ "<soapenv:Body> "
+ "<tem:login>" + login + "</tem:login>"
+ "<tem:password>" + password + "</tem:password>"
+ "<tem:ipAddress>" + ipAddress + "</tem:ipAddress>"
+ "</soapenv:Body>"
+ "</soapenv:Envelope>";

这是正确的还是我采取了错误的解决方案?有什么建议吗?

Tnx

安德里亚

最佳答案

您的方法看起来很简单,但您需要对要插入的字符串进行 XML 转义。

否则,如果字符串包含保留的 XML 字符(例如 <),接收方可能无法解析您的请求。 。考虑一下有人使用 </tem:login>作为他的密码:)

诸如 Guava 或 Apache commons 之类的库包含 XML 转义符,请参阅此线程以获取指针: Best way to encode text data for XML in Java?

或者,您可以只包含您自己的:

public static String xmlEscape(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < sb.length(); i++) {
char c = s.charAt(i);
if ("<&\">'".indexOf(c) != -1) {
sb.append("&#" + ((int) c) + ";");
} else {
sb.append(c);
}
}
return sb.toString();
}

因此您的填充代码将类似于以下内容:

soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">" 
+ "<soapenv:Header/>"
+ "<soapenv:Body> "
+ "<tem:login>" + xmlEscape(login) + "</tem:login>"
+ "<tem:password>" + xmlEscape(password) + "</tem:password>"

附:切勿通过网络以明文形式发送登录数据!您可能希望在您的服务中使用 https 而不是 http。

关于java - 如何用 Java 为该 WS 创建 SOAP 请求信封?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20106602/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com