📄 jax2.htm
字号:
<P>1. 生成占位程序</P>
<P>2. 编写客户端代码</P>
<P>3. 编译客户端代码</P>
<P>4. 将客户端的类打包成一个JAR文件</P>
<P>5. 运行客户端</P>
<P>接下来分别描述每个步骤。</P>
<P><B><A name=sheng></A>生成占位程序</B></P>
<P>生成占位程序前,先确定按照“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#bu">部署服务</A>”中的指令安装了Hello.wsdl文件。要生成占位程序,进入<JWSD_HOME>/docs/tutorial/examples/jaxrpc/hello目录,然后输入下面命令:</P>
<BLOCKQUOTE>
<P>ant generate-stubs</P></BLOCKQUOTE>
<P>该命令以如下方式运行wscompile工具:</P>
<BLOCKQUOTE>
<P>wscompile –gen:client –d build/client<BR>-classpath
build/shared config.xml</P></BLOCKQUOTE>
<P>-gen:client选项指示wscompile生成客户端类,例如占位程序。-d选项指定生成文件的目标目录。更多信息请参见“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#wscompile">wscompile工具</A>”部分。</P>
<P>wscompile工具根据从Hello.wsdl和config.xml文件中读出的信息生成文件。当服务被部署时,Hello.wsdl文件被安装在Tomcat上。Hello.wsdl的位置由config.xml文件的<wsdl>元素指定,如下所示:</P>
<BLOCKQUOTE>
<P> <?xml version="1.0"
encoding="UTF-8"?><BR>
<configuration
xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"><BR>
<wsdl location=<BR>
"http://localhost:8080/hello-jaxrpc/hello?WSDL"<BR>
packageName="hello"/><BR></configuration>
</P></BLOCKQUOTE>
<P>wscompile工具执行的任务依赖于config.xml文件的内容。关于config.xml文件的更多信息请参见“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#pei">配置文件</A>”部分。高级用户可能希望检验XML模式文件:<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/common/jax-rpc-ri-config.xsd。</P>
<P><B>编写客户端代码</B></P>
<P>HelloClient是一个独立的程序,它调用HelloWorld服务的sayHello方法。它进行这一调用是借助于占位程序,用作远程服务的代理的本地对象。由于占位程序是在运行前生成的(由wscompile),因此它通常被称为静态占位程序。</P>
<P>HelloClient调用名为createProxy的私有方法来生成占位程序。注意该方法中的代码是实现特有的,可能不可移植,因为它依赖于MyHello_Impl对象。(MyHello_Impl类在前面部分由wscompile生成。)生成占位程序后,客户端程序将占位程序转换成HelloIF,服务定义接口类型。</P>
<P>HelloClient的源代码如下所示:</P>
<BLOCKQUOTE>
<P>package hello;</P>
<P>import javax.xml.rpc.Stub;</P>
<P>public class HelloClient {<BR> public
static void main(String[] args)
{<BR> try
{<BR>
Stub stub =
createProxy();<BR>
HelloIF hello =
(HelloIF)stub;<BR>
System.out.println(hello.sayHello("Duke!"));<BR> }
catch (Exception ex)
{<BR>
ex.printStackTrace();<BR>
}<BR> }<BR>
private static Stub createProxy()
{<BR> //
注意:MyHello_Impl是实现特有的。<BR>
return (Stub)(new
MyHello_Impl().getHelloIFPort());<BR>
}<BR>} </P></BLOCKQUOTE>
<P><B>编译客户端代码</B> </P>
<P>由于客户端代码引用了占位程序类,在编译客户端前确定执行了“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#sheng">生成占位程序</A>”中的指令。要编译客户端,进入<JWSDP_HOME>/docs/tutorial/examples/jaxrpc/hello目录,然后输入如下命令:
ant compile-client </P>
<P><B>打包客户端</B></P>
<P>要将客户端打包成一个JAR文件,输入下列命令: ant jar-client
该命令生成dist/hello-client.jar文件。 </P>
<P><B>运行客户端</B> </P>
<P>要运行HelloClient程序,输入: ant run 程序应该显示如下信息: Hello Duke! 命令ant
run的目标是执行命令: java –classpath <I><cpath></I>
hello.HelloClient
classpath包含前面部分生成的hello-client.jar文件,以及属于Java
WSDP的一些JAR文件。为了能够远程运行客户端,所有这些JAR文件必须存储在远程的客户机上。</P>
<H4><A name=die></A><B>迭代开发</B> </H4>
<P>为了演示开发的每个步骤,前面部分要求输入一些ant命令。但是,在迭代开发的过程中输入所有这些命令是不合适的。为了节约时间,在第一次部署完服务后,可以通过这些步骤来迭代:
1. 测试应用。 2. 编辑源文件。
3. 执行ant build来生成可部署的WAR文件。
4. 执行ant redeploy来撤销部署,再部署服务。
5. 执行ant build-static,为具有静态占位程序的客户端生成JAR文件。
6. 执行ant run。 </P>
<H4><B>实现特有的特性</B> </H4>
<P>为了实现JAX-RPC规范,Java WSDP需要一些规范中没有说明的特性。这些特性是Java
WSDP所特有的,可能与其它供应商提供的实现不兼容。对于JAX-RPC,Java WSDP的实现特有的特性有:</P>
<UL>
<LI>config.xml-参见例子中“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#sheng">生成占位程序</A>”。
<LI>jaxrpc-ri.xml-参见例子中“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.1.htm#da">打包WAR文件</A>”。
<LI>约束-前面的例子中,约束在hello-jaxrpc.war文件中,它是针对特定实现的。(但是,hello-portable.war文件不是针对特定实现的。)
<LI>占位程序-占位程序在hello-client.jar文件中。注意,HelloClient程序用具体例子说明MyHelloImpl,一个静态占位程序类,它是针对特定实现的。由于动态客户不包含静态占位程序,因此它们没有这一限制。关于更多的动态客户的信息,请参见“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#dong">一个动态代理客户实例</A>”和“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#yi">动态调用接口(DII)客户实例</A>”。
<LI>工具-wsdeploy和wscompile。
<LI>支持集合-参见<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.1.htm#table11">表11-1</A>。
</LI></UL>
<H2><A name=leixing></A>JAX-RPC支持的类型</H2>
<P>幕后,JAX-RPC将Java编程语言中的类型映射成XML/WSDL定义的类型。例如,JAX-RPC将java.lang.String类映射成xsd:string
XML数据类型。应用程序开发者不必知道这些映射的详细信息,但要知道并不是所有的Java
2平台的类都能进行映射,标准版(J2SETM平台)可以被用作JAX-RPC中的某个方法的参数或返回类型。 </P>
<H4><B>J2SE SDK</B><B>类</B> </H4>
<P>JAX-RPC支持下面的J2S2 SDK类:</P>
<BLOCKQUOTE>
<P>java.lang.Boolean
<BR>java.lang.Byte<BR>java.lang.Double<BR>java.lang.Float<BR>java.lang.Integer
<BR>java.lang.Long <BR>java.lang.Short <BR>java.lang.String
<BR>java.math.BigDecimal<BR>java.math.BigInteger
<BR>java.util.Calender <BR>java.util.Date </P></BLOCKQUOTE>
<P>JAX-RPC的发布版还支持java.util.Collection接口的一些实现类,参见<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.2.htm#table112">表11-2</A>。
</P>
<P><A name=table112></A><EM>表11-2 支持的Java Collection框架类
</EM></P>
<TABLE cellSpacing=0 cellPadding=0 border=1>
<TBODY>
<TR>
<TD vAlign=top width=299>java.util.Collection子接口</TD>
<TD vAlign=top width=299>实现类</TD></TR>
<TR>
<TD vAlign=top width=299>List</TD>
<TD vAlign=top width=299>ArrayList LinkedList Stack
Vector</TD></TR>
<TR>
<TD vAlign=top width=299>Map</TD>
<TD vAlign=top width=299>HashMap Hashtable Properties
TreeMap</TD></TR>
<TR>
<TD vAlign=top width=299>Set</TD>
<TD vAlign=top width=299>HashSet
TreeSet</TD></TR></TBODY></TABLE>
<H4><B>原始数据类型</B> </H4>
<P>JAX-RPC支持下列Java编程语言中的原始数据类型: boolean byte double float int
long short </P>
<P><B>数组</B></P>
<P>JAX-RPC还支持由JAX-RPC支持的数据类型构成的数组。例如,支持的数组可以是int[]和String[]。多维数组,例如BigDecimal[][],也是支持的。
</P>
<P><B>应用程序类</B> </P>
<P>JAX-RPC还支持应用程序中编写的类。例如,在一个订购处理应用程序中,可以提供名为Order、LineItem、Product的类。JAX-RPC规范以值类型的方式访问这些类,因为它们的值(或状态)可以用作方法的参数或返回值在客户和远程服务间传递。
要被JAX-RPC支持,一个应用程序类必须满足下列规则: l
必须要有一个公共的默认的构造器 l
必须没有实现(直接或间接地)java.rmi.Remote接口
l 它的字段必须是JAX-RPC所支持的类型
类可以包含公有的、私有的或受保护的字段。因为在远程调用过程中它的值将被传递(或返回),因此字段必须满足这些需求:
l 公有字段不能是final或临时变量
l 非公有字段必须有相应的getter和setter方法
</P>
<P><B>JavaBeans</B><B>组件</B> </P>
<P>JAX-RPC还支持JavaBeans组件,但组件必须满足与应用程序类相同的规则。另外,一个JavaBean组件必须为它的每个属性提供getter和setter方法。Bean属性的类型必须是JAX-RPC所支持的类型。关于JavaBeans组件的例子请参见“JAX-RPC分布式服务”部分。
</P>
<H2><A name=dong></A><FONT size=4>一个动态代理客户端实例</FONT></H2>
<P>在“<A
href="http://gceclub.sun.com.cn/staticcontent/html/webservices/web_services_tutorial/jax-rpc.11/11.1.htm#jian">简单实例:HelloWorld</A>”部分,客户端使用一个静态的占位程序作为代理。相对照而言,这部分的客户端实例通过动态代理,运行时生成的类来调用远程过程。在代理类生成前,客户端通过查找WSDL文档来获得服务的信息。</P>
<P><B>动态代理HelloClient清单</B> </P>
<P>这儿是<JWSD_HOME>/docs/tutorial/examples/jaxrpc/proxy目录中<A
href="http://java.sun.com/webservices/docs/1.1/tutorial/examples/jaxrpc/proxy/HelloClient.java">HelloClient.java</A>文件的完整清单。
</P>
<BLOCKQUOTE>
<P>package proxy;<BR>import java.net.URL;<BR>import
javax.xml.rpc.Service; <BR>import
javax.xml.rpc.JAXRPCException; <BR>import
javax.xml.namespace.QName; <BR>import
javax.xml.rpc.ServiceFactory; <BR>public class
HelloClient { <BR>public static void
main(String[] args) {
<BR>try
{<BR>
String UrlString
=<BR>
"http://localhost:8080/ProxyHelloWorld.wsdl";<BR>
String nameSpaceUri =
"http://proxy.org/wsdl";<BR>
String serviceName = "HelloWorld";
<BR>
String portName =
"HelloIFPort";<BR>
URL helloWsdlUrl = new
URL(UrlString);<BR>
ServiceFactory
serviceFactory
=<BR>
ServiceFactory.newInstance(); <BR>
Service
helloService =
<BR>
serviceFactory.createService(helloWsdlUrl,<BR> new
QName(nameSpaceUri,
serviceName));<BR>
HelloIF
myProxy = (HelloIF)
helloService.getPort(<BR>
new
QName(nameSpaceUri,
portName),<BR> proxy.HelloIF.class);<BR> System.out.println(myProxy.sayHello("Buzz"));<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -