本文介绍一个非常实用的java客户端工具类来调用c# webservices和apache xml rpc server,这个类的源码是从网上下载的,我在博客网做项目的时候一直使用这个类来调试c# webservices和metaweblog api。顺便在这里也给大家介绍一下c#如何处理此类发送的xml数据。
使用这个类不用安装任何第三方工具,因为采用http的方式发送xml文件,所以你只需要安装好jdk就可以了。执行此类还可以获得webservices或xml rpc server返回的xml字符流,你可以根据返回的xml数据来进行其他程序处理。通过这种方式实现了java平台和.net平台的数据交换和webservice调用。
下面是此类的源代码soapclient4xg.java:
/**
* 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);
}
}
}
}
}
编译:javac soapclient4xg.java
运行的命令格式: java -classpath . soapclient4xg http://localhost/bokeservices/service1.asmx c:loginreq.xml http://tempuri.org/userloginreq,不过先不要运行上面的命令,先介绍一下命令行的意思,http://localhost/bokeservices/service1.asmx是c# webservice的地址,c:loginreq..xml里的内容是调用的webservice方法的xml文件, http://tempuri.org是webservice方法的命名空间,一定要有,否则调用失败,如果你在c# webservices中使用了方法默认的命名空间的话,就使用http://tempuri.org,否则要与c#中定义的一致,userloginreq是c# webservices的方法名。注意xml文件中的方法名和参数名是与c# webservices的方法名、参数名是一一对应的(参数顺序是可以颠倒的)。
我先介绍一个简单的例子(c:loginreq.xml),这个xml文件调用了远程c# webservice的userloginreq方法,并带useracc(用户名)和userpwd(口令)两个参数,调用成功后c#会自动返回一个xml格式的soap包。
<?xml version="1.0" encoding="utf-8"?>
<soap:envelope xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:body>
<userloginreq xmlns="http://tempuri.org/">
<useracc>baozheng</useracc>
<userpwd>mypwd</userpwd>
</userloginreq>
</soap:body>
</soap:envelope>
现在看一下c# webservices的userloginreq的方法的定义:
public struct userloginresp
{
public string useracc;
public int result;
}
[webmethod]
public userloginresp userloginreq(string useracc,string userpwd,int reqfrom)
{
…
}
注意结构userloginresp,c# webservices返回soap信息时会自动将userloginresp结构转换成xml的格式。
用此类做xml rpc server 的客户端也很简单,下文是一个客户端rpc.xml文件,调用了xml rpc server 端实现的metaweblog.deletepost方法。
<?xml version="1.0" encoding="utf-8"?>
<methodcall>
<methodname>metaweblog.deletepost</methodname>
<params>
<param><value>appkeyvalue</value></param>
<param><value>746</value></param>
<param><value>baozheng</value></param>
<param><value>hello123</value></param>
</params>
</methodcall>
调用命令的格式:
java -classpath %classpath%;. soapclient4xg. http://192.168.25.97:8080/bokeexmlrpc/xml-rpc rpc.xml
对比调用webservices的命令行,可以看出调用xml rpc server的命令行少一个方法名参数。http://192.168.25.97:8080/bokeexmlrpc/xml-rpc 是提供xml rpc 调用的server端servlet地址,关于如何用apache xml rpc技术实现metalogapi的帖子将在近期整理发布。
注:上文的左右尖括号为保证正常发贴替换为全角。
作者:王保政
qq:19803446
msn:baozhengw999@hotmail.com
email:baozhengw@netease.com
闽公网安备 35060202000074号