写一个基于JAX-RPC的webservice程序-HelloWorld
1.概念
JAX-RPC:Java API for XML-based RPC(Remote Procedure Call)
2.JAX-RPC响应过程
先上图:
2.1客户端首先会调用Stub对象的方法--Stub是远程对象的一个存根,简单理解成一个远程服务对象的代理也可以
2.2Stub对象发起对JAX--RPC运行时环境的调用
2.3JAX-RPC运行时环境负责将Stub对方法的调用转化正SOAP 消息,并且将SOAP消息通过HTTP协议发送出去
2.4服务器端的JAX-RPC运行时环境接收到客户端的SOAP http请求,将SOAP消息解析成对方法的调用
2.5JAX-RPC运行时环境调用Tie对象的中相应的方法
2.6Tie对象调用远程接口中接口方法(HelloWorld接口)
2.7JAX-RPC负责将方法调用的响应结果封装成SOAP消息,并且将消息以http协议发送给客户端
2.8客户端JAX-RPC接收到服务器端响应的SOAP消息,将其解析成对HelloClientProgram程序的方法调用
3.配置服务器端服务HelloWorld!
3.1服务器端接口Hello
a)服务接口必须继承自Remote接口
b)接口中不允许有常量
c)接口中的方法需抛出RemoteException
d)接口中的方法参数和返回值类型有约束,适应以下类型
java中8中基本数据类型及其包装类,String,BigDecimal,BigInteger,Calendar,java.util.Date,List,ArrayList,LinkedList,Stack,Vector,Map,HashMap,HashTeable,TreeMap,Properties,Set,HashSet,TreeSet,数组类型,java bean对象作为参数或结果要求必须实现Remote接口,必须提供默认构造函数,java bean中的字段必须是上面提到的可支持的类型,getter&setters
package com.crazycoder2010.jaxrpc; import java.rmi.Remote; import java.rmi.RemoteException; public interface Hello extends Remote { public String sayHello(String s) throws RemoteException; }
3.2服务器端接口实现类
package com.crazycoder2010.jaxrpc; import java.rmi.RemoteException; public class HelloImpl implements Hello { @Override public String sayHello(String s) throws RemoteException { return "Hello " + s; } }3.3准备部署
先下载一个Sun Java Application Server8.2,安装
再下载sun的webservice开发工具包Java Web Services Developer Pack,并安装,安装的时候会提示让指定Application Server的目录,将其指定为刚才的安装目录即可
在WEB-INF\下新建一个xml文件命名为jaxrpc-ri.xml,内容如下,这个文件定义了我们要暴露接口的一些信息,我们使用sun的wsdeploy工具来部署,提供这个文件那是必须滴
<?xml version="1.0" encoding="UTF-8"?> <webServices xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/dd" version="1.0" targetNamespaceBase="http://www.crazycoder2010.com/wsdl" typeNamespaceBase="http://www.crazycoder2010.com/types" urlPatternBase="/ws"> <endpoint name="MyHello" displayName="Kevin's First HelloWorld Service" description="A simple web service" interface="com.crazycoder2010.jaxrpc.Hello" implementation="com.crazycoder2010.jaxrpc.HelloImpl" /> <endpointMapping endpointName="MyHello" urlPattern="/helloKevin" /> </webServices>
将jwsdp-2.0\jaxrpc\lib下的3个jar包复制到工程的WEB-INF\lib下
将jwsdp-2.0\saaj\lib下的2个jar包复制到工程的WEB-INF\lib下
(注意这两个jar包下的saaj-api.jar 和saaj-impl.jar在jdk1.6运行有问题,纠结了很久,终于找到了解决方法,只要去下载最新的saaj-api.jar和saaj-impl.jar即可,切记切记)
将jwsdp-2.0\fastinfoset\lib 下的1个jar包复制到工程的WEB-INF\lib下
将jwsdp-2.0\jwsdp-shared\lib\mail.jar,activation.jar包复制到工程的WEB-INF\lib下
3.4将工程压缩打成一个war包
可以在工程目录下运行 jar cvf helloApp.war * 或直接使用eclipse工具提供的export 工具直接搞定即可
3.5将war包用wsdeploy工具打包成一个webservice服务包
wsdeploy -o hello.war helloApp.war
这个hello.war就是我们最终的包含webservice的功能完整的war包了,直接复制到tomcat的webapp下即可
3.6测试服务器端
浏览器中输入:http://localhost:8080/hello/helloKevin 就可以看到我们暴露的服务了,说明服务器端已经ok了
4.配置客户端调用
4.1配置config.xml(位于工程目录\share目录下)
<?xml version="1.0" encoding="UTF-8"?> <configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"> <wsdl location= "http://localhost:8080/hello/helloKevin?WSDL" packageName="com.crazycoder2010.jaxrpc"/> </configuration>4.2打开命令行,切换到工程所在目录,运行命令
wscompile -gen:client -d client_module -classpath build shared/config.xml
解释:client_module为当前工程下的一个文件夹,用来存放最终生成的stub模块
-classpath build 笔者项目工程编译过的java文件是输出到build文件夹里i的
shared/config.xml这个见4.1节介绍
运行后就可以在在client_module目录下看到生成了一堆的class文件了,如图
4.3将stub打成jar包
命令行切换到client_module目录下,执行jar cvf hello-client.jar * 会在client_module下生成一个hello-client.jar包
4.4创建客户工程jax-rpc-client
为client工程引入jar包 hello-client.jar (4.3打包的那个)
为client工程引入jar包jwsdp-2.0\jaxrpc\lib下的3个
为client工程引入jar包jwsdp-2.0\jwsdp-shared\lib\mail.jar,activation.jar
为client工程引入jar包jwsdp-2.0\saaj\lib下的两个jar包
为client工程引入jar包 jwsdp-2.0\fastinfoset\lib下的1个jar包
编写客户端主程序HelloClient
package com.crazycoder2010.jaxrpc; import java.rmi.RemoteException; import javax.xml.rpc.Stub; public class HelloClient { public static void main(String[] args) throws RemoteException { Stub stub = createProxy(); Hello hello = (Hello)stub; System.out.println(hello.sayHello("Kevin")); } private static Stub createProxy() { return (Stub)(new MyHello_Impl().getHelloPort()); } }运行,控制台输出Hello,Kevin