随着SOA的流行,webservice开发也变得相当的热门。许多企业都将自己的网站迁移到soa的架构。今天我们来一起体验一下通过axis来创建、发布和调用webservice的过程。如果大家不太了解SOA请访问下面网址(http://www-900.ibm.com/cn/software/rational/solution/tech/soa_design.shtml

        在开始之前我默认大家已经具有axis的安装经验,如果对axis安装和配置发布有任何问题请看http://yangyang.javaeye.com/blog/56519 和http://yangyang.javaeye.com/blog/56552两篇文章。let's go!

       首先我们先假设一个需求。我们需要一个service,功能是给手机充值,充值成功后返回操作代码和消息。给手机充值需要手机号、充值金额、操作类型。操作成功或者失败后返回操作代码和消息。在这里我们将客户端的请求和服务器端响应进行了包装代码如下:

java 代码

1.          package com.yy.ws;   <o:p></o:p>

2.          public class ClientRequest {   <o:p></o:p>

3.              private String opType;   <o:p></o:p>

4.              private int amount;   <o:p></o:p>

5.              private String phoneNumber;   <o:p></o:p>

6.              public int getAmount() {   <o:p></o:p>

7.                  return amount;   <o:p></o:p>

8.              }   <o:p></o:p>

9.              public void setAmount(int amount) {   <o:p></o:p>

10.               this.amount = amount;   <o:p></o:p>

11.           }   <o:p></o:p>

12.           public String getOpType() {   <o:p></o:p>

13.               return opType;   <o:p></o:p>

14.           }   <o:p></o:p>

15.           public void setOpType(String opType) {   <o:p></o:p>

16.               this.opType = opType;   <o:p></o:p>

17.           }   <o:p></o:p>

18.           public String getPhoneNumber() {   <o:p></o:p>

19.               return phoneNumber;   <o:p></o:p>

20.           }   <o:p></o:p>

21.           public void setPhoneNumber(String phoneNumber) {   <o:p></o:p>

22.               this.phoneNumber = phoneNumber;   <o:p></o:p>

23.           }   <o:p></o:p>

24.       }   <o:p></o:p>

 

optype代表操作类型,也可以用枚举类型。amount代表充值金额。phoneNumber代表手机号。

下面是服务器响应对象。如下:
java 代码

1.          package com.yy.ws;   <o:p></o:p>

2.          public class ServerResponse {   <o:p></o:p>

3.              private long resultCode;   <o:p></o:p>

4.              private String message;   <o:p></o:p>

5.              public String getMessage() {   <o:p></o:p>

6.                  return message;   <o:p></o:p>

7.              }   <o:p></o:p>

8.              public void setMessage(String message) {   <o:p></o:p>

9.                  this.message = message;   <o:p></o:p>

10.           }   <o:p></o:p>

11.           public long getResultCode() {   <o:p></o:p>

12.               return resultCode;   <o:p></o:p>

13.           }  <o:p></o:p>

14.           public void setResultCode(long resultCode) {   <o:p></o:p>

15.               this.resultCode = resultCode;   <o:p></o:p>

16.           }   <o:p></o:p>

17.       }   <o:p></o:p>

      

resultCode代表充值操作代码。message代表服务器端操作成功与否的消息。下面我们通过axis提供的一个工具org.apache.axis.wsdl.Java2WSDL.来产生wsdl文件。Java2WSDL是一个根据axis用户提供的webservice接口来产生相应的wsdl文件。在接口中我们定义了webservice的所有方法(服务)。如果大家不知道wsdl请查阅相应资料。http://www.ibm.com/developerworks/cn/webservices/ws-intwsdl/part1/#N10054

interface代码如下:

java 代码

1.   package com.yy.ws;   

2.     

3.   public interface MobileBoss {   

4.          public ServerResponse charge(ClientRequest req);   

5.   }  

这个接口定义了一个名字为MobileBosswebservice,其中一个服务名字为charge。下面我们通过Java2WSDL工具生成这个wswsdl文件。

进入接口所在源文件的文件夹(包的最上层,如果包名是com.yy.ws则需要在com的上一层目录下如classes),我的文件夹结构是classes/com/yy/ws/所以我需要进入源文件目录:

C:"ws>cd classes

在控制台输入如下命令:

C:"ws"classes>  java org.apache.axis.wsdl.Java2WSDL  -o mb.wsdl -l "http://localhost:8080/axis/services/MobileBoss" -n "urn:MobileBoss" -p"com.yy.ws" "urn:MobileBoss"  com.yy.ws.MobileBoss

参数说明: -o  输出wsdl文件名称

                   -l 访问的url

                  -n 命名空间

                 -p  包名 命名空间的名字(urn:是命名空间的缩写,必须有!)

               com.yy.ws.MobileBoss 是接口的全路径。包名+类名。

如果没有抛出异常,我们就可以在C:"ws"classes文件夹下找到mb.wsdl.

这个mb.wsdl文件描述的这个ws的所有信息,包括请求响应对象、访问url、端口等等信息。这个文件是由axisJava2WSDL  工具生成的,怎么样?是不是很方便啊!

       下面我们来通过org.apache.axis.wsdl.WSDL2Java来生成相应的webservice代码。

进入wsdl文件所在目录。

C:"ws> cd classes

键入如下命令:

C:"ws"classes> java org.apache.axis.wsdl.WSDL2Java -o . -d Session -s -S true  -Nurn:MobileBoss com.yy.ws mb.wsdl

参数说明: -o 输出文件所在目录( .-代表当前目录

                   -s生成server端绑定代码

                   -d发布范围

                  -S是否产生发布和撤销webservicedeploy.wsddundeploy.wsdd文件。ture代表生成发布文件。

                  -Nurn:命名空间 包名

                 mb.wsdl - wsdl文件名。

如果没有抛出异常,我们就可以在C:"ws"classes文件夹下找到下面几个文件:

ClientRequest.java

MobileBoss.java

MobileBossService.java

MobileBossServiceLocator.java

MobileBossSoapBindingImpl.java

MobileBossSoapBindingSkeleton.java

MobileBossSoapBindingStub.java

ServerResponse.java

deploy.wsdd undeploy.wsdd
 

除了最后两个发布文件以外最重要的有两个文件,即MobileBossSoapBindingImpl.javaMobileBossServiceLocator.java

MobileBossSoapBindingImpl代码如下:

1.   java 代码

/**

2.           * MobileBossSoapBindingImpl.java  

3.           *  

4.           * This file was auto-generated from WSDL  

5.           * by the Apache Axis 1.3 Oct 05, 2005 (05:23:37 EDT) WSDL2Java emitter.  

6.           */  

7.            

8.          package com.yy.ws;   

9.            

10.       public class MobileBossSoapBindingImpl implements com.yy.ws.MobileBoss{   

11.           public com.yy.ws.ServerResponse charge(com.yy.ws.ClientRequest in0) throws java.rmi.RemoteException {   

12.               return null;   

13.           }   

14.         

15.       }   

我们需要在这个webservice中实现自己的业务方法!我们加入如下业务代码:

java 代码

1.          /**  

2.           * MobileBossSoapBindingImpl.java  

3.           *  

4.           * This file was auto-generated from WSDL  

5.           * by the Apache Axis 1.3 Oct 05, 2005 (05:23:37 EDT) WSDL2Java emitter.  

6.           */  

7.            

8.          package com.yy.ws;   

9.            

10.       public class MobileBossSoapBindingImpl implements com.yy.ws.MobileBoss {   

11.         

12.           /*  

13.            *   

14.            * implements the service methods  

15.            */  

16.           public com.yy.ws.ServerResponse charge(com.yy.ws.ClientRequest req)   

17.                   throws java.rmi.RemoteException {   

18.               String bizInfo = req.getPhoneNumber() + "/" + req.getOpType() + "/"  

19.                       + req.getAmount();   

20.               System.out.println(bizInfo);   

21.               System.out.println(req.getPhoneNumber() + "is charged successfully!");   

22.               ServerResponse res = new ServerResponse();   

23.               res.setMessage(bizInfo);// save service informations.   

24.               res.setResultCode(8888);// save result code.   

25.               return res;   

26.           }   

27.         

28.       }   

好了现在我们将webservice的实现代码发布到tomcataxis web应用中。如将你的代码拷贝到axis/WEB-INF/classes

进入你的deploy.wsdd所在目录。

cd C:"tomcat5"webapps"axis"WEB-INF"classes"com"yy"ws

输入如下命令:

C:"tomcat5"webapps"axis"WEB-INF"classes"com"yy"ws>   java     org.apache.axis.client.AdminClient  deploy.wsdd

AdminClient  -一个axis发布工具,会自动地将你的webservice发布到WEB-INF下的server-config.wsdd文件中。如果显示:

Processing file deploy.wsdd
<Admin>Done processing</Admin>

则表示发布成功!

       好了,现在我们已经完成了创建和发布过程,接下来我们来进行最后一步工作——调用我们写的webservice! 

java 代码

1.          package com.yy.ws.test;   

2.            

3.          import java.net.MalformedURLException;   

4.          import java.rmi.RemoteException;   

5.            

6.          import javax.xml.rpc.ServiceException;   

7.            

8.          import com.yy.ws.ClientRequest;   

9.          import com.yy.ws.MobileBoss;   

10.       import com.yy.ws.MobileBossService;   

11.       import com.yy.ws.MobileBossServiceLocator;   

12.       import com.yy.ws.ServerResponse;   

13.         

14.       public class Test {   

15.           public static void main(String args[]) throws ServiceException, MalformedURLException, RemoteException{   

16.               ClientRequest req = new ClientRequest();   

17.               req.setAmount(1000);   

18.               req.setOpType("charge");   

19.               req.setPhoneNumber("13912345678");   

20.               MobileBossService sl = new MobileBossServiceLocator();   

21.               //URL url = new URL("http://localhost:8080/axis/services/MobileBoss");   

22.               //s.getMobileBoss(url);   

23.               MobileBoss mb = sl.getMobileBoss();//default port   

24.               ServerResponse resp = mb.charge(req);   

25.               System.out.println("client result:"+resp.getResultCode()+""nclient message:"+resp.getMessage());   

26.           }   

27.       }   

结果如下:

服务器端显示:

13912345678|charge|1000
13912345678is charged successfully!

客户端显示:

client result:8888

client message:13912345678|charge|1000

      服务器段成功返回消息,大功告成!不是很难吧?!这篇文章的所有代码我都测试过,全部可以直接使用。希望能够对大家有所帮助。