/*title:   web service入门学习笔记
**date:   2007/01/16
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
web   service入门学习笔记
最近要做一个java项目,里面用到了webservice技术,
经过一个多月的磕磕绊绊的摸索,总算如了点门。现将我的学习笔记贴出来,供大家参考。
说明,本笔记第七部分主要参考了  
[url]http://blog.csdn.net/lin_bei/archive/2006/11/07/1371131.aspx[/url]
的内容,由于这位兄弟翻译的不是很通顺,我就按照自己的理解来改编成了
hellowrold的例子:-)。
其他部分为我原创,转载时请注明出处。
一、实验环境
  win2k   +   jdk1.6     +   javee5.0     +   Myeclipse5.1
jdk和javee5.0均可从
[url]http://java.sun.com/javase/downloads/index.jsp[/url]
下载,安装文件名为
jdk-6-windows-i586.exe
java_ee_sdk-5_02-windows.exe
没有myeclipse的也可以用eclipse代替,只要ide能执行
ant脚本就可以.

/*title:   web   service入门学习笔记(二)
**date:   2007/01/16
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
 
二、第一个最简单的例子
jsee5安装以后会在系统中建立一个Application   Server   pe9,这是sun自带的网络服务器,
和tomcat、weblogic的性质类似。
在D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws下有一个自带的web   service入门例子,
(D:\Sun\SDK\为我机器上javaee5的安装路径)
我们就先实验它,来理解webservice的本质
1、把jdk的安装路径如D:\Java\jdk1.6.0\bin   加到系统的path环境变量中
2、运行sun自带的网络服务器,具体方法为
        开始-> 程序-> Sun   Microsystems-> Application   Server   PE   9-> Start   Default   Server
        然后当弹出的cmd窗口中出现提示“按任意键继续时”输入回车,窗口会关闭,此时在浏览器输入
       
[url]http://localhost:8080[/url] ,应该出现如下内容:
              Sun   Java   System   Application   Server   Platform   Edition   9.0    
Your   server   is   up   and   running!
说明服务器已经启动了
3、在Myeclipse打开刚才的例子目录D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws
下的build.xml文件,这个一个ant脚本,具体含义我们以后再讲,现在先执行它
3、在build.xml文件中单击右键,在弹出菜单中选择 "run   as "-> "1   ant   build ",此时build.xml里的
内容会被执行,在Myeclipse的console中会输出:
buildfile:   D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws\build.xml
init:
compile-deploy-service:
          [echo]   d:/Sun/SDK
get-artifacts-windows:
get-artifacts-unix:
get-artifacts:
compile-client:
        [javac]   Compiling   1   source   file   to   D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws\build
run-client-windows:
          [exec]   Hello   result   =   Hello   Administrator!
run-client-unix:
run-client:
all:
BUILD   SUCCESSFUL
Total   time:   43   seconds
其中
[exec]   Hello   result   =   Hello   Administrator!
的输出结果说明客户端调用服务器的webservice已经成功。
第一个例子就完成了。我们下面会对这个例子进行详细讲解.
/*title:   web   service入门学习笔记(三)、(四)
**date:   2007/01/16
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
三、WebService的本质
从搞c的程序员的眼光来看,webservice实际上就是用java实现的rpc(远端过程调用),
或者说是dll的变形。服务器把它的接口对外发布成一个wsdl文件,客户端根据这个wsdl的内容生成
本地的代理类,再通过代理类调用远端的接口,代理再把接口的执行执行结果回传给客户端,
进行下一步处理。
 
 
问题点数:0 回复次数:128 显示所有回复显示星级回复显示楼主回复 修改 删除 举报 引用 回复  
 

四、例子源代码剖析
D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws(以后简称为hello-jaxws)
项目里的源文件只有三个  
hello-jaxws\src\endpoint\Hello.java       提供webservice的服务器端实现类
hello-jaxws\src\client\Client.java         调用webservice的客户端测试类
hello-jaxws\build.xml                                   自动编译的ant脚本
下面我们把这三个文件的内容看一下
1、服务器端的service实现类文件Hello.java,
/*   src\endpoint\Hello.java文件的内容   */
package   endpoint;
import   javax.jws.WebService;
@WebService
public   class   Hello
{
      public   String   getHello(String   name)
        {
                return   "Hello   "   +   name   +   "! ";
        }
}
有这个文件可以看出,编写一个service的实现类,把编写普通的java类
差不多,只不过又多了三点
①要在该类前一个@WebService说明,
②引入javax.jws.WebService;
③在公开的方法前加@WebMethod说明,如果不加的话,
所有的public方法都会自动变成service的对外接口.

2、客户端测试类的实现文件
/*   src\client\Client.java文件的内容   */
package   client;
import   javax.xml.ws.WebServiceRef;
import   endpoint.HelloService;
import   endpoint.Hello;
public   class   Client
{
        @WebServiceRef(wsdlLocation= "
[url]http://localhost:8080/Hello/HelloService?WSDL[/url] ")
        static   HelloService   service;
       
        public   static   void   main(String[]   args)
        {
                Client   client   =   new   Client();
                client.doHello();
        }
       
        public   void   doHello()
        {
                try
                {
                        Hello   port   =   service.getHelloPort();
                        String   ret   =   port.getHello(System.getProperty( "user.name "));
                        System.out.println( "Hello   result   =   "   +   ret);
                }
                catch(Exception   e)
                {
                        e.printStackTrace();
                }
        }
}
客户端调用代码要点为:
①导入WebServiceRef包
import   javax.xml.ws.WebServiceRef;
②导入本地生成的stub类,另外编译时也要指明stub类的路径
import   endpoint.HelloService;
import   endpoint.Hello;
③指明服务器的wsdl路径
@WebServiceRef(wsdlLocation= "
[url]http://localhost:8080/myhello/HelloService?WSDL[/url] ")
④声明一个静态的service对象
static   HelloService   service;
⑤对要调用的远程方法声明一个代理对象,通过代理来调用真正的远程方法
Hello   port   =   service.getHelloPort();
        String   ret   =   port.getHello(System.getProperty( "user.name "));
3、ant   脚本build.xml



       

       
       
       
       
       
       
       

       
               
               
       
       
       
       
               
       

       
               
                          
               
               
                          
               
       

       
               
               
                                        srcdir= "./src "  
                        includes= "endpoint/** "
                        destdir= "${autodeploydir} "
                        classpath= "${javaee.home}/lib/j2ee.jar "  
                />
               
                     
                               
                               
                     

               
               
                               
               
               
                               
               
       
       

       
               
                        [url]http://$[/url]{javaee.server.name}:${javaee.server.port}/Hello/HelloService?WSDL
"/>
               
       
       
               
                        [url]http://$[/url]{javaee.server.name}:${javaee.server.port}/Hello/HelloService?WSDL
"/>
               
       
   
       
               
                       
               
       
       
       
       

       
               
                                
                        
       
          
               
                                
                        
       
       
       
       
       
       
       


       
               
               
               

       
       
               
       
这个脚本有许多在windows平台用不到的步骤,下面我们对其进行改造,把它精简一下.
/*title:   web   service入门学习笔记(五)
**date:   2007/01/18
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
 

五、精简后的ant脚本
1、卸载webservice
执行原build.xml里的clean和 undeploy任务,把安装好的webservice删除掉,具体办法为:
(1)在myeclipse里打开build.xml文件
(2)在build.xml文件里单击右键菜单中的 " "run   as "-> "2   ant   build... " ",
(3)在弹出的对话框中只选择clean和undelpoy任务。 然后单击 "run "按钮。
此时再访问
[url]http://localhost:8080/Hello/HelloService?WSDL[/url] ,出现http   404错误,说明卸载成功
2、简化后的脚本内容,在hello-jaxws目录下新建一个buildtest.xml文件,内容为






 

        


















[url]http://$[/url]{javaee.server.name}:${javaee.server.port}/Hello/HelloService?WSDL
"   />




                        srcdir= "./src "  
                        includes= "endpoint/** "                      
                        destdir= "${autodeploydir} "          
                        classpath= "${javaee.home}/lib/j2ee.jar "  
                />























3、运行结果
在myeclipse里执行这个刚才编写的buildtest.xml脚本,console里的输出为
Buildfile:   D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws\buildtest.xml
compile-deploy-service:
        [mkdir]   Created   dir:   D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws\build
          [echo]   d:/Sun/SDK
        [javac]   Compiling   1   source   file   to   D:\Sun\SDK\domains\domain1\autodeploy
get-artifacts-windows:
get-artifacts:
compile-client:
        [javac]   Compiling   1   source   file   to   D:\Sun\SDK\samples\javaee5\webservices\hello-jaxws\build
run-client-windows:
          [exec]   Hello   result   =   Hello   Administrator!
run-client:
all:
BUILD   SUCCESSFUL
Total   time:   50   seconds
也执行成功
 
/*title:   web   service入门学习笔记(六)
**date:   2007/01/19
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
六、一个通用的ant脚本
1、脚本内容
  上面的buildtest.xml脚本虽然对原始的build.xml做了精简,但是还不够通用,
比如服务器的类名和方法名等等都写死了,显然还不适合我们的需要,于是我又写了一个相对通用的脚本
mybuild.xml,内容如下



















    value= "
[url]http://$[/url]{javaee.server.name}:${javaee.server.port }
    /${serviceclass}/${serviceclass}Service?WSDL "   />



















                        srcdir= "./src "  
                        includes= "${serverclasspath}/** "                      
                        destdir= "${autodeploydir} "          
                        classpath= "${javaee.home}/lib/j2ee.jar "  
                />


















2、脚本的使用方式
以后再写自己service时,只要按实际情况改变以下4条语句中的value值就可以了
    



/*title:   web   service入门学习笔记(七)
**date:   2007/01/19
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
 
七、命令行开发过程
      通过以上的学习,我们知道如何在ant脚本和ide环境中开发一个简单的webservice.
但是作为搞技术的人特别是搞c的人来看,上面的过程隐藏了太多的东西,
对我们有钻研精神的人,自然就想搞清楚脚本背后的过程。
假设我们的机器上没有ide环境和ant工具,
我们如何“手工”编译出自己的webservice呢?
这就是本节要讲述的内容--只用命令行工具开发webservice.
0、设置环境变量
把jdk和javaee的路径如
D:\Java\jdk1.6.0
D:\Sun\SDK\bin加到系统的path变量中去
1、建立项目目录
首先建立一个项目的目录,名为WebTest,项目目录下又包含三个子目录
  src\             本目录用于存放源代码,
  build\         本目录用于存放输出的文件
  deploy\       本目录用于对服务器打包
   
2、编写服务器类实现文件
在项目的src目录下建立一个个子目录endpoint,
在这个endpoint子目录下新建一个Hello.java文件,内容如下
/*src\endpoint\Hello.java文件      
提供webservice的服务器端实现类
*/
package   endpoint;
 
import   javax.jws.WebService;
import   javax.jws.WebMethod;
 
@WebService
public   class   Hello
{
@WebMethod
        public   String   getHello(String   name)
      {
                return   "Hello   "   +   name   +   "! ";
        }
  }
3、编译服务器类
①在build目录下建立一个子目录classes
    ②在命令行执行如下命令
    cd   WebTest     ;进入项目目录
    javac   -classpath   d:/Sun/SDK/lib/javaee.jar   -d   ./build/classes   src/endpoint/Hello.java     ;编译服务器类
    执行完后会产生一个build\classes\endpoint\Hello.class文件
   
4、生成wsdl文件
①在build目录下建立一个子目录generated
②生成wsdl文件,执行
wsgen   -cp   ./build/classes   -keep   -d   ./build/classes   -r   ./build/generated   -wsdl     endpoint.Hello
执行完成会在./build/generated产生两个文件
HelloService.wsdl
HelloService_schema1.xsd
并且在\build\class\endpoint下建立一个jaxws目录,下面有4个文件
GetHello.java                                                
GetHello.class
GetHelloResponse.java
GetHelloResponse.class
这些文件与与前面所说的ant脚本中生成的
D:\Sun\SDK\domains\domain1\generated\ejb\j2ee-modules\endpoint_Hello\endpoint\jaxws
下的文件相同
5、将服务器打包,做成war文件
①建立打包所需要的目录
      在项目的deploy目录下建立一个子目录/WEB-INF,
    WEB-INF子目录下再建立两个子目录
    classes/     用于存放服务器端类
    wsdl/           用于存放wsdl文件
②将各输出文件或目录拷贝到相应的目录下
(1)把build\classes\endpoint整个目录拷贝到deploy/WEB-INF/class目录下
(2)把build\generated目录下的两个文件
HelloService.wsdl、HelloService_schema1.xsd拷贝到
deploy/WEB-INF/wsdl目录下
③在deploy/WEB-INF/   目录下新建一个web.xml文件,内容为

[url]http://java.sun.com/xml/ns/javaee[/url]
"
xmlns:j2ee= "
[url]http://java.sun.com/xml/ns/javaee[/url] "
xmlns:xsi= "
[url]http://www.w3.org/2001/XMLSchema-instance[/url] "   version= "2.5 "
xsi:schemaLocation= "
[url]http://java.sun.com/xml/ns/javaee[/url]
[url]http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd[/url] ">
WebTier   for   the   Hello   Service
HelloWAR

Endpoint   for   Hello   Web   Service
HelloWebService
Hello
endpoint.Hello
0


Hello
/HelloService


54


④将service打包,执行
(1)cd   WebTest\deploy     ;进入打包目录
(2)jar   cvf   hello.war   *     ;将当前目录下的所有内容打包到hello.war文件中
 
6、将service 类发布到网络服务器上
①启动sun   服务器
方法为
开始-> 程序-> Sun   Microsystems-> Application   Server   PE   9-> Start   Default   Server
②在项目目录下建立一个passwd文件,内容是sun服务器admin用户的密码,例如
AS_ADMIN_PASSWORD=testtesttest
③将hello.war发布到服务器上,执行
(1)cd   WebTest     ;进入项目目录
(2)发布服务器包,注意这个命令是在一行执行的,
我为了书写方便而断行。分号后面是注释
asadmin   deploy  
--user   admin                           ;管理员用户名
--passwordfile   passwd         ;密码文件名,就是我们刚才写的passwd文件
--host   localhost                  
--port   4848     ;管理端口号
--contextroot   myhello     ;上下文根名称
--upload=true    
--target   server
deploy/hello.war
④在浏览器中输入地址
[url]http://localhost:8080/myhello/HelloService?WSDL[/url]
如果浏览器能显示出正确的内容,就说明成功。
7、生成客户端的stub类
①在项目的build\classes目录下建立一个stub子目录
②执行
(1)cd   WebTest       ;进入项目子目录
(2)wsimport   -keep   -d   ./build/classes/stub  
[url]http://localhost:8080/myhello/HelloService?WSDL[/url]
执行完成后会在build/classes/stub下建立一个endpoint目录,下面有这些文件
GetHello.java
GetHelloResponse.java
Hello.java
HelloService.java
GetHello.class
GetHelloResponse.class
Hello.class
HelloService.class
ObjectFactory.class
ObjectFactory.java
package-info.java
package-info.class
这些文件和ant脚本中import执行的结果一样
8、编写客户端测试程序
在项目的src目录下建立一个子目录client,在这个目录下面建立一个
Client.java文件,内容为
//   src\client\Client.java文件   调用服务器提供的webservice的测试类  
package   client;
import   javax.xml.ws.WebServiceRef;
import   endpoint.HelloService;
import   endpoint.Hello;
public   class   Client
{
        @WebServiceRef(wsdlLocation= "
[url]http://localhost:8080/myhello/HelloService?WSDL[/url] ")
        static   HelloService   service;
public   static   void   main(String[]   args)
        {
                Client   client   =   new   Client();
                client.doHello();
        }
                public   void   doHello()
        {
                try
                {
                        Hello   port   =   service.getHelloPort();
                        String   ret   =   port.getHello(System.getProperty( "user.name "));
                        System.out.println( "Hello   result   =   "   +   ret);
                }
                catch(Exception   e)
                {
                        e.printStackTrace();
                }
        }
}
9、编译客户端程序
执行
(1)cd   WebTest     ;进入项目目录
(2)javac   -classpath   ./build/classes/stub;d:/Sun/SDK/lib/javaee.jar;d:/Sun/SDK/lib/appserv-ws.jar   -d   ./build/classes/stub   src/client/Client.java    
执行成功后会在F:\exercise\java\WebTest\build\classes目录下建立一个
client目录,下面有一个Client.class文件
10、运行客户端程序
(1)cd   WebTest\build\classes\stub     ;进入client的上级目录
(2)set     APPCPATH=.           ;设置环境变量APPCPATH,不然运行appclient程序时会出一堆莫名奇妙的错误
(3)> appclient   client.Client运行测试程序,结果为
Hello   result   =   Hello   Administrator!
执行成功
 
/*title:   web   service入门学习笔记(八)
**date:   2007/01/19
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
八、小结
开发webservice的基本步骤为
1、编写服务器端,要点有
①导入WebService包和WebMethod包
import   javax.jws.WebService;
import   javax.jws.WebMethod;
②实现的服务类前加@WebService符号
③为了代码清晰,类提供的公开方法前加@WebMethod符号,这个不写对编译也没影响,
2、编译服务器端,要点为
①javac命令的classpath选项中要有javaee.jar的路径,如
javac   -classpath   d:/Sun/SDK/lib/javaee.jar   -d   ./build   src/endpoint/Hello.java
②用wsgen命令生成wsdl文件.
③将服务器端打包
注意如果是sun的服务器,那么把service类直接编译到
javaee5安装目录\domains\domain1\autodeploy下,可以自动完成②和③的工作。
我们介绍的sun自带的入门脚本就是这么做的。
3、在客户端机器上自动生成stub类,要点为
①客户机上必须也装有jdk和javaee5
②用wsimport工具将服务器传过来的wsdl文件转换成本地的stub类
4、编写客户端调用代码,要点:
①导入WebServiceRef包
import   javax.xml.ws.WebServiceRef;
②导入本地生成的stub类,如
import   endpoint.HelloService;
import   endpoint.Hello;
③指明服务器的wsdl路径
@WebServiceRef(wsdlLocation= "
[url]http://localhost:8080/myhello/HelloService?WSDL[/url] ")
④声明一个静态的service对象
static   HelloService   service;
⑤对要调用的远程方法声明一个代理对象,通过代理来调用真正的远程方法
Hello   port   =   service.getHelloPort();
        String   ret   =   port.getHello(System.getProperty( "user.name "));
5、编译客户端调用程序,注意classpath参数中要有
①stub类的路径
②javaee.jar的路径
③appserv-ws.jar的路径
6、用appclient执行客户端程序,要点为
①进入到客户端程序的上级目录
②把APPCPATH的值设置为当前目录 "   .   "
③appclient的第一个参数为客户端程序名,
    后面的参数是传给客户端程序本身的命令行参数。
/*title:   web   service入门学习笔记(九)
**date:   2007/01/19
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]
*/
九、本文中用到的文件
1、WebTest项目文件列表
WebTest\passwd 保存密码的文件,手工建立
WebTest\src   子目录   手工建立,内容为
endpoint\Hello.java     服务器类的实现文件
client\Client.java       客户类的实现文件
WebTest\build
generated   子目录,手工建立,内容为
HelloService.wsdl 由wsgen命令生成
HelloService_schema1.xsd   由wsgen命令生成
classes   子目录,手工建立,内容为
endpoint\Hello.class     由javac命令生成
endpoint\jaxws子目录,由wsgen命令自动生成,内容为
GetHello.java
GetHelloResponse.java
GetHello.class
GetHelloResponse.class
stub   子目录,手工建立,内容为:
client\Client.class   由javac命令生成
endpoint   子目录   由wsimport命令自动生成,内容为:
GetHello.java
GetHelloResponse.java
Hello.java
HelloService.java
ObjectFactory.java
package-info.java
package-info.class
GetHello.class
GetHelloResponse.class
Hello.class
HelloService.class
ObjectFactory.class
WebTest\deploy子目录   手工建立,内容为
hello.war   将WEB-INF子目录打包后生成的文件,由jar命令生成
WEB-INF       打包的输入目录,手工建立。内容包括:
web.xml       手工建立
classes\endpoint子目录   为build\classes\endpoint的拷贝
wsdl子目录,由build\generated拷贝而来
2、生成的HelloService.wsdl文件的内容

[url]http://endpoint/[/url]
"   name= "HelloService "   xmlns= " [url]http://schemas.xmlsoap.org/wsdl/[/url] "   xmlns:tns= " [url]http://endpoint/[/url] "   xmlns:xsd= " [url]http://www.w3.org/2001/XMLSchema[/url] "   xmlns:soap= " [url]http://schemas.xmlsoap.org/wsdl/soap/[/url] ">
   
       
            [url]http://endpoint/[/url]
"   schemaLocation= "HelloService_schema1.xsd "/>
       
   
   
       
   
   
       
   
   
       
           
           
       
   
   
        [url]http://schemas.xmlsoap.org/soap/http[/url]
"   style= "document "/>
       
           
           
               
           
           
               
           

       
   
   
       
           
       
   
十、致谢
在学习WebService的过程中,我得到了csdn   java版的叶锋城朋友的许多指点,
饼子堂的兄弟们也给了很多有用的资料,这里一并表示谢意。本文也算是我给这些
朋友们的一个汇报和总结,呵呵。
(--end  
/*title:   web   service入门学习笔记
**date:   2007/01/23
**author:laomai
**url:  
[url]http://blog.csdn.net/laomai/[/url]*/