web service入门学习笔记

时间:2023-02-24 19:34:59
 

一、实验环境

win2k   +   jdk1.6     +   javee5.0     +   Myeclipse5.1
jdk
javee5.0均可从

http://java.sun.com/javase/downloads/index.jsp
下载,安装文件名为

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:   http://blog.csdn.net/laomai/
*/
 

二、第一个最简单的例子

jsee5安装以后会在系统中建立一个Application   Server   pe9,这是sun自带的网络服务器,
tomcatweblogic的性质类似。

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窗口中出现提示按任意键继续时输入回车,窗口会关闭,此时在浏览器输入

        http://localhost:8080,
应该出现如下内容:

              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里的

内容会被执行,在Myeclipseconsole中会输出
:
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:   http://blog.csdn.net/laomai/
*/

三、WebService的本质

从搞c的程序员的眼光来看,webservice实际上就是用java实现的rpc(远端过程调用)
或者说是dll的变形。服务器把它的接口对外发布成一个wsdl文件,客户端根据这个wsdl的内容生成

本地的代理类,再通过代理类调用远端的接口,代理再把接口的执行执行结果回传给客户端,

进行下一步处理。

四、例子源代码剖析

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= "http://localhost:8080/Hello/HelloService?WSDL ")
        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= "http://localhost:8080/myhello/HelloService?WSDL ")
声明一个静态的service对象

static   HelloService   service;
对要调用的远程方法声明一个代理对象,通过代理来调用真正的远程方法

Hello   port   =   service.getHelloPort();
        String   ret   =   port.getHello(System.getProperty( "user.name "));

3
ant   脚本
build.xml
<!--   ant  
脚本build.xml的内容
  -->
<?xml   version= "1.0 "   encoding= "UTF-8 "?>
<project   name= "hello-jaxws "   default= "all "   basedir= ". ">
        <!--   include   user   specific   build   properties   -->

<!--  
导入预先j2ee预先写好的设置文件
-->
        <property   file= "../../../bp-project/build.properties "/>
        <property   file= "${user.home}/build.properties "/>
        <property   file= "../../../bp-project/app-server.properties "/>
       
        <!--  
设置发布目录和类的输出目录
  -->
        <property   name= "autodeploydir "   value= "${javaee.domaindir}/autodeploy "/>
        <property   name= "classesdir "   value= "./build "/>

<!--  
设置java的类库路径
  -->
        <path   id= "classpath ">
                <pathelement   location= "${javaee.home}/lib/j2ee.jar "/>
                <pathelement   location= "${classesdir} "/>
        </path>
       
        <!--  
项目的最终任务
  -->
        <target   name= "all "   depends= "run-client ">
                <!--antcall   target= "restore "/-->
        </target>

<!--  
测试操作系统环境
-->
        <target   name= "init ">
                <condition   property= "windows ">
                        <os   family= "windows "   />  
                </condition>
                <condition   property= "unix ">
                        <os   family= "unix "   />  
                </condition>
        </target>

<!--  
编译服务器端并把它自动发布到sun的服务器上
  -->
        <target   name= "compile-deploy-service "   depends= "init ">
                <mkdir   dir= "${classesdir} "/>
                <echo   message= "${javaee.home} "/>
                <javac  
                        srcdir= "./src "  
                        includes= "endpoint/** "
                        destdir= "${autodeploydir} "
                        classpath= "${javaee.home}/lib/j2ee.jar "  
                />
                <waitfor   maxwait= "100 "   maxwaitunit= "second ">
                      <or>
                                <available   file= "${autodeploydir}/endpoint/Hello.class_deployed "/>
                                <available   file= "${autodeploydir}/endpoint/Hello.class_deployFailed "/>
                      </or>
                </waitfor>
                <condition   property= "deploy_succeeded ">
                                <available   file= "${autodeploydir}/endpoint/Hello.class_deployed "/>
                </condition>
                <condition   property= "deploy_failed ">
                                <available   file= "${autodeploydir}/endpoint/Hello.class_deployFailed "/>
                </condition>
        </target>

        <target   name= "get-artifacts "   depends= "compile-deploy-service,get-artifacts-windows,get-artifacts-unix "/>

<!--  
生成客户端所需的
stub   -->
        <target   name= "get-artifacts-windows "   if= "windows ">
                <exec   executable= "${javaee.home}/bin/wsimport.bat ">
                        <arg   line= "-keep   -d   ${classesdir}   http://${javaee.server.name}:${javaee.server.port}/Hello/HelloService?WSDL "/>
                </exec>
        </target>

        <target   name= "get-artifacts-unix "   if= "unix ">
                <exec   executable= "${javaee.home}/bin/wsimport ">
                        <arg   line= "-keep   -d   ${classesdir}   http://${javaee.server.name}:${javaee.server.port}/Hello/HelloService?WSDL "/>
                </exec>
        </target>

    <!--  
编译客户端
  -->
        <target   name= "compile-client "   depends= "get-artifacts ">
                <javac   srcdir= "./src/client "   destdir= "${classesdir} ">
                        <classpath   refid= "classpath "/>
                </javac>
        </target>
       
       
        <target   name= "run-client "   depends= "compile-client,run-client-windows,run-client-unix "/>

<!--  
执行客户端
  -->
        <target   name= "run-client-windows "   if= "windows ">
                <exec   executable= "${javaee.home}/bin/appclient.bat "   dir= "${classesdir} ">
                        <arg   value= "client.Client "/>        
                </exec>        
        </target>

        <target   name= "run-client-unix "   if= "unix ">  
                <exec   executable= "${javaee.home}/bin/appclient "   dir= "${classesdir} "   failifexecutionfails= "false ">
                        <arg   value= "client.Client "/>        
                </exec>        
        </target>
       
        <!--  
以下几个任务用与清理和卸载
-->
        <!--  
删除生成的类文件
-->
        <target   name= "clean ">
        <delete   dir= "${classesdir} "/>
        </target>


<!--  
删除和卸载服务器的
webservice-->
        <target   name= "restore ">
                <delete>
                <fileset   dir= "${autodeploydir}/endpoint "   includes= "Hello*.* "/>
                </delete>
        </target>

        <target   name= "undeploy ">
                <antcall   target= "restore "/>
        </target>
</project>

这个脚本有许多在windows平台用不到的步骤,下面我们对其进行改造,把它精简一下
.

/*title:   web   service
入门学习笔记(五)

**date:   2007/01/18
**author:laomai
**url:   http://blog.csdn.net/laomai/
*/

五、精简后的ant脚本

1、卸载webservice
执行原build.xml里的clean undeploy任务,把安装好的webservice删除掉,具体办法为:

(1)
myeclipse里打开build.xml文件

(2)
build.xml文件里单击右键菜单中的
" "run   as "-> "2   ant   build... " ",
(3)
在弹出的对话框中只选择cleanundelpoy任务。 然后单击 "run "按钮。

此时再访问http://localhost:8080/Hello/HelloService?WSDL,出现http   404错误,说明卸载成功


2
、简化后的脚本内容,在hello-jaxws目录下新建一个buildtest.xml文件,内容为

<?xml   version= "1.0 "   encoding= "UTF-8 "?>
<project   name= "hello-jaxws "   default= "all "   basedir= ". ">
<!--   javaee
安装目录的设置,代替了原来脚本中的导入语句
  -->
<property   name= "javaee.home "   value   =   "d:/Sun/SDK "/>
<property   name= "javaee.domaindir "   value= "${javaee.home}/domains/domain1 "/>
<property   name= "javaee.server.name "   value= "localhost "/>
<property   name= "javaee.server.port "   value= "8080 "/>

  <!--  
设置发布目录和类的输出目录
  -->
<property   name= "autodeploydir "   value= "${javaee.domaindir}/autodeploy "/>
<property   name= "classesdir "   value= "./build "/>        

<!--  
设置java类库路径
  -->
<path   id= "classpath ">
<pathelement   location= "${javaee.home}/lib/j2ee.jar "/>
<pathelement   location= "${classesdir} "/>
</path>

<target   name= "all "   depends= "run-client ">
<!--antcall   target= "restore "/-->
</target>

<target   name= "run-client "   depends= "compile-client,run-client-windows "   />

<!--  
运行测试类,为项目的最后一个步骤
-->
<target   name= "run-client-windows ">
<exec   executable= "${javaee.home}/bin/appclient.bat "   dir= "${classesdir} ">
<arg   value= "client.Client "   />
</exec>
</target>

<!--  
编译测试webservice的客户类,为项目的第三个步骤,本步骤的输出文件为

${classesdir}/client/Client.class
-->

<target   name= "compile-client "   depends= "get-artifacts ">
<javac   srcdir= "./src/client "   destdir= "${classesdir} ">
<classpath   refid= "classpath "   />
</javac>
</target>

<target   name= "get-artifacts "   depends= "compile-deploy-service,get-artifacts-windows "/>

<!--  
本步骤的目的是生成客户端的stub文件,是项目的第二个步骤,本步骤的输出文件为

${classesdir}下面自动生成了如下的文件

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
-->
<target   name= "get-artifacts-windows ">
<exec   executable= "${javaee.home}/bin/wsimport.bat ">
<arg   line= "-keep   -d   ${classesdir}   http://${javaee.server.name}:${javaee.server.port}/Hello/HelloService?WSDL "   />
</exec>
</target>

<!--  
本步骤的目的是编译服务器类,并自动产生wsdl.是项目的第一个步骤,本步骤的主要输出文件为

${autodeploydir}/endpoint/Hello.class
${autodeploydir}/domain1/autodeploy/endpoint/Hello.class_deployed

d:/Sun/SDK/domains/domain1/applications/j2ee-modules
下建立一个endpoint_Hello目录,



d:/Sun/SDK/domains/domain1/generated/ejb/j2ee-modules建立一个

endpoint_Hello
目录,这个目录下又建立了一个endpoint/jaxws目录,里面有如下内容

GetHello.java
GetHelloResponse.java
GetHello.class
GetHelloResponse.class

D:/Sun/SDK/domains/domain1/generated/xml/j2ee-modules/下建立一个

endpoint_Hello
目录,这个目录下又有一个WEB-INF子目录,内容为

wsdl
子目录


sun-web.xml    
文件

web.xml            
文件

webservices.xml    
文件

wsdl
子目录下又有两个文件

HelloService.wsdl
HelloService_schema1.xsd
当我们在浏览器输入http://localhost:8080/Hello/HelloService?WSDL时,显示的正是

这个
domains/domain1/generated/xml/j2ee-modules/endpoint_Hello/WEB-INF/wsdl
文件的内容

-->

<target   name= "compile-deploy-service ">
<mkdir   dir= "${classesdir} "   />
<echo   message= "${javaee.home} "   />
<javac  
                        srcdir= "./src "  
                        includes= "endpoint/** "                      
                        destdir= "${autodeploydir} "          
                        classpath= "${javaee.home}/lib/j2ee.jar "  
                />
<waitfor   maxwait= "100 "   maxwaitunit= "second ">
<or>
<available   file= "${autodeploydir}/endpoint/Hello.class_deployed "/>
<available   file= "${autodeploydir}/endpoint/Hello.class_deployFailed "/>
</or>
</waitfor>
<condition   property= "deploy_succeeded ">
<available   file= "${autodeploydir}/endpoint/Hello.class_deployed "/>
</condition>
<condition   property= "deploy_failed ">
<available   file= "${autodeploydir}/endpoint/Hello.class_deployFailed "/>
</condition>
</target>


<!--  
以下的任务用于清理和卸载
-->
<target   name= "clean ">
<delete   dir= "${classesdir} "/>
</target>

<target   name= "restore ">
<delete>
<fileset   dir= "${autodeploydir}/endpoint "   includes= "Hello*.* "/>
</delete>
</target>

<target   name= "undeploy ">
<antcall   target= "restore "/>
</target>
</project>

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:   http://blog.csdn.net/laomai/
*/

六、一个通用的ant脚本

1、脚本内容
 
上面的buildtest.xml脚本虽然对原始的build.xml做了精简,但是还不够通用,

比如服务器的类名和方法名等等都写死了,显然还不适合我们的需要,于是我又写了一个相对通用的脚本

mybuild.xml
,内容如下

<?xml   version= "1.0 "   encoding= "UTF-8 "?>

<project   name= "hello-jaxws "   default= "all "   basedir= ". ">
<!--   javaee
安装目录的设置,代替了原来脚本中的导入语句
  -->
<property   name= "javaee.home "   value   =   "d:/Sun/SDK "/>
<property   name= "javaee.domaindir "   value= "${javaee.home}/domains/domain1 "/>
<property   name= "javaee.server.name "   value= "localhost "/>
<property   name= "javaee.server.port "   value= "8080 "/>

<!--  
设置发布目录和类的输出目录
  -->
<property   name= "autodeploydir "   value= "${javaee.domaindir}/autodeploy "/>
<property   name= "classesdir "   value= "./build "/>

<!--  
设置java类库路径
  -->
<path   id= "classpath ">
<pathelement   location= "${javaee.home}/lib/j2ee.jar "/>
<pathelement   location= "${classesdir} "/>
</path>


<!--  
提供服务的类名
  -->
<property   name= "serviceclass "   value= "Hello "   />
<property   name= "serverclasspath "   value= "endpoint "   /> <!--  
服务器所在的package名称

也就是Hello.java文件中第一句

package   endpoint;
语句中的
endpoint
-->
<!--  
调用webservice的测试类名
-->
<property   name   =   "clientclass "   value= "Client "/>
<property   name   =   "clientclasspath "   value= "client "/> <!--  
测试类所在的package名称,

         
也就是Client.java文件中第一句

        package   client;
语句中的
client;
        -->
<!--  
生成的wsdl文件的uri的格式,注意value的值分成两行写时有问题,
 
这里为了阅读方便而分行,拷贝时必须放到一行

我还没找到ant脚本里的续行符是什么
:-(  
-->
<property   name= "wsdluri "  
    value= "http://${javaee.server.name}:${javaee.server.port}
    /${serviceclass}/${serviceclass}Service?WSDL "   />

<target   name= "all "   depends= "run-client ">
<!--   antcall   target= "restore "/   -->
</target>

<target   name= "run-client "   depends= "compile-client,run-client-windows "   />

<!--  
运行测试类,为项目的最后一个步骤
-->
<target   name= "run-client-windows ">
<exec   executable= "${javaee.home}/bin/appclient.bat "   dir= "${classesdir} ">
<arg   value= "${clientclasspath}.${clientclass} "   />
</exec>
</target>

<!--  
编译测试webservice的客户类,为项目的第三个步骤,本步骤的输出文件为

${classesdir}/client/Client.class
-->

<target   name= "compile-client "   depends= "get-artifacts ">
<javac   srcdir= "./src/${clientclasspath} "   destdir= "${classesdir} ">
<classpath   refid= "classpath "   />
</javac>
</target>

<target   name= "get-artifacts "   depends= "compile-deploy-
asadmin   deploy   --user   admin   --password   laomailaomai   --host   localhost   --port   4848   --contextroot   hello   --upload=true   --target   server
service,ge
t-artifacts-windows "/>

<!--  
生成客户端的stub
  -->
<target   name= "get-artifacts-windows ">
<exec   executable= "${javaee.home}/bin/wsimport.bat ">
<arg   line= "-keep   -d   ${classesdir}   ${wsdluri} "   />
</exec>
</target>

<!--  
本步骤的目的是编译服务器类,并自动产生wsdl文件
-->
<target   name= "compile-deploy-service ">
<echo   message= "${javaee.home} "   />
<javac  
                        srcdir= "./src "  
                        includes= "${serverclasspath}/** "                      
                        destdir= "${autodeploydir} "          
                        classpath= "${javaee.home}/lib/j2ee.jar "  
                />
<waitfor   maxwait= "100 "   maxwaitunit= "second ">
<or>
<available   file= "${autodeploydir}/${serverclasspath}/${serviceclass}.class_deployed "/>
<available   file= "${autodeploydir}/${serverclasspath}/${serviceclass}.class_deployFailed "/>
</or>
</waitfor>
<condition   property= "deploy_succeeded ">
<available   file= "${autodeploydir}/${serverclasspath}/${serviceclass}.class_deployed "/>
</condition>
<condition   property= "deploy_failed ">
<available   file= "${autodeploydir}/${serverclasspath}/${serviceclass}.class_deployFailed "/>
</condition>
</target>

<!--  
以下的任务用于清理和卸载
-->
<target   name= "clean ">
<delete   dir= "${autodeploydir}/${serverclasspath} "/>
<delete   dir= "${classesdir}/${serverclasspath} "/>
<delete   dir= "${classesdir}/${clientclasspath} "/>
</target>
</project>

2
、脚本的使用方式

以后再写自己service时,只要按实际情况改变以下4条语句中的value值就可以了

<property   name= "serviceclass "   value= "Hello "   />    
<property   name= "serverclasspath "   value= "endpoint "   />
<property   name   =   "clientclass "   value= "Client "/>
<property   name   =   "clientclasspath "   value= "client "/>


/*title:   web   service
入门学习笔记(七)

**date:   2007/01/19
**author:laomai
**url:   http://blog.csdn.net/laomai/
*/

七、命令行开发过程

      通过以上的学习,我们知道如何在ant脚本和ide环境中开发一个简单的webservice.
但是作为搞技术的人特别是搞c的人来看,上面的过程隐藏了太多的东西,

对我们有钻研精神的人,自然就想搞清楚脚本背后的过程。

假设我们的机器上没有ide环境和ant工具,

我们如何手工编译出自己的webservice呢?

这就是本节要讲述的内容--只用命令行工具开发
webservice.

0
、设置环境变量

jdkjavaee的路径如

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文件,内容为

<?xml   version= "1.0 "   encoding= "UTF-8 "?>
<web-app   xmlns= "http://java.sun.com/xml/ns/javaee "
xmlns:j2ee= "http://java.sun.com/xml/ns/javaee "
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance "   version= "2.5 "
xsi:schemaLocation= "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd ">
<description> WebTier   for   the   Hello   Service </description>
<display-name> HelloWAR </display-name>
<servlet>
<description> Endpoint   for   Hello   Web   Service </description>
<display-name> HelloWebService </display-name>
<servlet-name> Hello </servlet-name>
<servlet-class> endpoint.Hello </servlet-class>
<load-on-startup> 0 </load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name> Hello </servlet-name>
<url-pattern> /HelloService </url-pattern>
</servlet-mapping>
<session-config>
<session-timeout> 54 </session-timeout>
</session-config>
</web-app>
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

在浏览器中输入地址

http://localhost:8080/myhello/HelloService?WSDL

如果浏览器能显示出正确的内容,就说明成功。


7
、生成客户端的stub

在项目的build/classes目录下建立一个stub子目录

执行

(1)cd   WebTest       ;
进入项目子目录

(2)wsimport   -keep   -d   ./build/classes/stub   http://localhost:8080/myhello/HelloService?WSDL

执行完成后会在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= "http://localhost:8080/myhello/HelloService?WSDL ")
        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:   http://blog.csdn.net/laomai/
*/

八、小结

开发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= "http://localhost:8080/myhello/HelloService?WSDL ")
声明一个静态的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:   http://blog.csdn.net/laomai/
*/

九、本文中用到的文件

1WebTest项目文件列表
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文件的内容

<?xml   version= "1.0 "   encoding= "UTF-8 "   standalone= "yes "?>
<definitions   targetNamespace= "http://endpoint/ "   name= "HelloService "   xmlns= "http://schemas.xmlsoap.org/wsdl/ "   xmlns:tns= "http://endpoint/ "   xmlns:xsd= "http://www.w3.org/2001/XMLSchema "   xmlns:soap= "http://schemas.xmlsoap.org/wsdl/soap/ ">
    <types>
        <xsd:schema>
            <xsd:import   namespace= "http://endpoint/ "   schemaLocation= "HelloService_schema1.xsd "/>
        </xsd:schema>
    </types>
    <message   name= "getHello ">
        <part   name= "parameters "   element= "tns:getHello "/>
    </message>
    <message   name= "getHelloResponse ">
        <part   name= "parameters "   element= "tns:getHelloResponse "/>
    </message>
    <portType   name= "Hello ">
        <operation   name= "getHello ">
            <input   message= "tns:getHello "/>
            <output   message= "tns:getHelloResponse "/>
        </operation>
    </portType>
    <binding   name= "HelloPortBinding "   type= "tns:Hello ">
        <soap:binding   transport= "http://schemas.xmlsoap.org/soap/http "   style= "document "/>
        <operation   name= "getHello ">
            <soap:operation   soapAction= " "/>
            <input>
                <soap:body   use= "literal "/>
            </input>
            <output>
                <soap:body   use= "literal "/>
            </output>
        </operation>
    </binding>
    <service   name= "HelloService ">
        <port   name= "HelloPort "   binding= "tns:HelloPortBinding ">
            <soap:address   location= "REPLACE_WITH_ACTUAL_URL "/>
        </port>
    </service>
</definitions>