Listing 1. The complete SOAP client
/**
* SOAPClient4XG. Read the SOAP envelope file passed as the second
* parameter, pass it to the SOAP endpoint passed as the first parameter, and
* print out the SOAP envelope passed as a response. with help from Michael
* Brennan 03/09/01
*
*
* @author Bob DuCharme
* @version 1.1
* @param SOAPUrl URL of SOAP Endpoint to send request.
* @param xmlFile2Send A file with an XML document of the request.
*
* 5/23/01 revision: SOAPAction added
*/
import java.io.*;
import java.net.*;
public class SOAPClient4XG {
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.err.println("Usage: java SOAPClient4XG " +
"http://soapURL soapEnvelopefile.xml" +
" [SOAPAction]");
System.err.println("SOAPAction is optional.");
System.exit(1);
}
String SOAPUrl = args[0];
String xmlFile2Send = args[1];
String SOAPAction = "";
if (args.length > 2)
SOAPAction = args[2];
// Create the connection where we're going to send the file.
URL url = new URL(SOAPUrl);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
// Open the input file. After we copy it to a byte array, we can see
// how big it is so that we can set the HTTP Cotent-Length
// property. (See complete e-mail below for more on this.)
FileInputStream fin = new FileInputStream(xmlFile2Send);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
// Copy the SOAP file to the open connection.
copy(fin,bout);
fin.close();
byte[] b = bout.toByteArray();
// Set the appropriate HTTP parameters.
httpConn.setRequestProperty( "Content-Length",
String.valueOf( b.length ) );
httpConn.setRequestProperty("Content-Type","text/xml; charset=utf-8");
httpConn.setRequestProperty("SOAPAction",SOAPAction);
httpConn.setRequestMethod( "POST" );
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
// Everything's set up; send the XML that was read in to b.
OutputStream out = httpConn.getOutputStream();
out.write( b );
out.close();
// Read the response and write it to standard out.
InputStreamReader isr =
new InputStreamReader(httpConn.getInputStream());
BufferedReader in = new BufferedReader(isr);
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
// copy method from From E.R. Harold's book "Java I/O"
public static void copy(InputStream in, OutputStream out)
throws IOException {
// do not allow other threads to read from the
// input or write to the output while copying is
// taking place
synchronized (in) {
synchronized (out) {
byte[] buffer = new byte[256];
while (true) {
int bytesRead = in.read(buffer);
if (bytesRead == -1) break;
out.write(buffer, 0, bytesRead);
}
}
}
}
}因为该 SOAP 客户机使用 HTTP 协议发送 XML SOAP 请求,所以大量必需做的工作就是 HTTP 设置。Java 提供了一个 HttpURLConnection 类,它有许多“设置”方法来正确设置每个 HTTP 参数,并且可以用简单的字符串来设置大多数参数。需要一点额外代码的一个 HTTP 参数是 Content-Length,所以SoapClient4XG通过在读取XML请求之后将它放到一个字节数组中,然后检查字节数组的长度特性来计算XML请求的长度。
可使用其它会代您设置这些 HTTP 参数的 HTTP 实现。Sun 开放源码的 Brazil Web 应用程序框架(请参阅参考资料)会自动处理 HTTP 问题, 并使处理适当 SOAP 错误更为容易,因为(不象早期的 HttpURLConnection 类)它是一个没有经过特定编写以用 Java 小应用程序减轻装入图像和其它 Web 资源工作的通用 HTTP 类。
运行它
Xmethods.com(请参阅参考资料)提供了一份在不断发展的公共可用 SOAP 服务列表。除了告诉您可选 SOAP 操作参数是否对每个服务是必需的之外,它们的许多描述还包括样本 XML 请求,所以我复制了对气温 SOAP 服务器的样本请求,添加了一些空白空间, 并在 zipcode 元素中替代了自己的邮政编码,如清单2所示。
清单2
Listing 2. SOAP XML Request to find out the temperature at zip code 11217
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
>
<SOAP-ENV:Body>
<ns1:getTemp xmlns:ns1="urn:xmethods-Temperature"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<zipcode xsi:type="xsd:string">11217</zipcode>
</ns1:getTemp>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
这个文件存储在名为 weattherreq.xml 的文件中,清单3中的命令行将它的内容发送到我获得样本 XML 的同一个 XMethods Web 页面上指定的 SOAP 端点 URL。
清单3
Listing 3. Using SOAPClient4XG to send the SOAP request
java SOAPClient4XG http://services.xmethods.net:80/soap/servlet/rpcrouter weatherreq.xml
如清单4中所示,SOAP 服务器发回 SOAP 响应,其中,当前温度存储在 response 元素中。
清单4
Listing 4. Temperature SOAP server's response
<?xml version='1.0' encoding='UTF-8'?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTempResponse xmlns:ns1="urn:xmethods-Temperature"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:float">50.0</return>
</ns1:getTempResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
因为这个 SOAP 客户机从您创建的 XML 文档文件(而不是从暗中为您创建的无访问权的文件)发送 SOAP 请求,所以,可以使用 XML 编辑器或文本编辑器来直接修改发送的 XML。更重要的是,该 SOAP 客户机显示了利用 SOAP 服务正在发展的选项是何等容易。 您只要命名服务的 SOAP 端点 URL,设置 HTTP 参数,发送表示方法的一些 XML 和要传递给它们的参数,然后等待响应。
一定要仔细检查可用于您喜爱的编程语言的 SOAP 库。通常,它们提供的错误处理比我的 SOAP 客户机的更好,提供的其它一些功能是用于强健应用程序开发的较好基础。请记住,所有这一切之下的简单性和这种简单协议所实现的强大功能。
(特别感谢 Michael Brennan 对 HTTP 问题的帮助。)
关于作者
Bob DuCharme (www.snee.com/bob) 是 Manning Publications 即将出版的 XSLT Quickly、Prentice Hall 的 XML: The Annotated Specification 与 SGML CD 及 McGraw Hill 的 Operating Systems Handbook 等书的作者。他为 XML.com 撰写了“Transforming XML”专栏, 并为 XML Magazine、XML Journal、IBM developerWorks 和 Prentice Hall 的 XML Handbook 撰稿。他经常在业界会议和用户组中演讲, 是 UDICo (www.udico.com) 负责企业文档的副总裁,他还制造了一个高性能小型中间件引擎和开发工具箱。他在哥伦比亚大学获得宗教方面的学士学位,在纽约大学获得计算机科学硕士学位,现在和他的妻子 Jennifer 及两个女儿 Madeline、Alice 生活在布鲁克林地区的 Park Slope。
『引自 IBM DW中国』
本文地址:http://com.8s8s.com/it/it12835.htm