使用 AXIS ( 版本1.4) 的方法


I 使用 AXIS(版本 1.4)的方法 邢飞 先配置好 JDK 和Tomcat。本文中使用的是JDK 5.0(源代码是 1.4 的)。Tomcat 是5.0.28。 下载 AXIS 1.4,地址 http://ws.apache.org/ 安装 AXIS 解压开 axis­1_4.zip ,将 axis­1_4/webapps/axis 拷贝到 $TOMCAT_HOME/webapps/ 下启动 tomcat,打开页面http://localhost:8080/axi s 页面正常,表示 axis 安装正确。 II 编写服务代码,如 需要发布的方法为 deposit , withdraw , getBalance 将编译好的 Account.class 文件放在文件夹 $TOMCAT_HOME/webapps/axis/WEB­INF/classes/com/hcycom/n7 中 如果使用 IDE,可以将输出文件夹设为 $TOMCAT_HOME/webapps/axis/WEB­INF/classes /* * Account.java */ package com.hcycom.n7; public class Account { public static int balance = 5000; // 存款 public String deposit (int amount) { String ret = "success"; if(amount > 0){ balance += amount; ret = "success"; } else { ret = "failure"; } return ret; } // 取款 public String withdraw (int amount) { String ret = "success"; if(amount > 0 && amount <= getBalance()){ balance ­= amount; ret = "success"; } else { ret = "failure"; } return ret; } // 获取余额 public int getBalance (){ return balance; } } III 编写部署描述符/home/xingfei/axis/ deploy.wsdd 内容如下 注意红色部分, account 表示服务的名称 java:RPC 表示调用服务的方法 com.hcycom.n7.Account 表示服务要调用的类的名称 * 表示要公布的方法,也可以公布一个类的某几个方法,使用逗号隔 IV 部署服务 account , 将axis 所需 jar 文件全部加到 classpath 中,执行以下命令 得到结果 Done processing 表示部署成功 也可以在 IDE 中使用如下方法部署 public class Deploy { public static void main(String[] args) { String[] arguments = { /home/xingfei/axis/ deploy.wsdd" }; org.apache.axis.client. AdminClient.main(arguments); } } % java org.apache.axis.client.AdminClient \ /home/xingfei/axis/ deploy.wsdd V 编写客户端调用代码,如下 其中红色部分为实际调用 account 服务的代码 package com.hcycom.n7; import javax.xml.namespace.QName; import org.apache.axis.client.Call; import org.apache.axis.client.Service; public class AccountClient { public static void main(String[] args) { String endpoint = "http://localhost:8080/axis/services/account"; try { Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress( new java.net.URL(endpoint) ); call.setOperationName(new QName("http://soapinterop.org/", "deposit ")); // 上面设置了操作为 deposit,这里意思是存 300 String ret = (String)call.invoke(new Object[]{new Integer(300)}); if(ret.equals("success")) { System.out.println("Deposit operation has been successfully done"); call.setOperationName(new QName("http://soapinterop.org/", "getBalance ")); // 操作为获取余额,这里得到整型的余额数 Integer balance = (Integer)call.invoke(new Object[0]); System.out.println("Now the balance is " + balance.intValue()); } else if(ret.equals("failure")) { System.out.println("Deposit operation has done something wrong"); } } catch (Exception e) { System.err.println(e.toString()); } } } VI 以上所写的,只适用于简单情况: 输入参数和输出结果都是基本类型 但是如果输入参数和输出结果中有我们自定义的复杂类型的话,就会出错。 因为客户端和服务器端使用的是 SOAP 消息进行通信。发送方将 Java 对象序列化为 XML,而接 收方又将 XML 反序列化成 Java 对象。双方应该知道Java 对象和 XML 之间是如何对应的,才能 正确的工作。 AXIS 可以在配置文件中使用, 来说明 Java 对象如何序列化 和反序列化。下面是一个例子: 其中 type 指我们要处理的 Java 对象。 serializer ,deserializer 指将这个 Java 对象进行序列化和反序列化的“工具”类 qname 指的是这个 Java 对象的命名空间 这些可以自己写,也可以由 AXIS 自动帮我们完成,下面介绍一个综合的例子,看看 AXIS 如何 为我们自动化的生成这些代码的。 例子是一个非常简单的用户管理服务。可以添加,删除和查看用户的信息。 用户有 name,age,sex 和contact 字段,而contact 又是一个 bean,由phone 和email 两 个字段。UserManager 是服务的定义,它定义了对 User 的操作。 以下将详细说明。 VII 服务定义 你要向外提供什么样的服务,可以先写一个 interface 来描述它。这个 interface 必需继承 自java.rmi.Remote ,而且每个方法必需抛出 java.rmi.RemoteException 。本例中的服 务定义为: 注意,红色部分是必需的,不然 AXIS 将不认识这个服务 package com.hcycom.user; import java.rmi.Remote; import java.rmi.RemoteException; public interface UserManager extends Remote { /** * add a user * 输入部分有复杂类型 */ public int addUser(User user) throws RemoteException ; /** * delete a user */ public int deleteUser(String name) throws RemoteException ; /** * get all the users * 输出为复杂类型 */ public User[] getAllUsers() throws RemoteException ; /** * get a user by name * 输出为复杂类型 */ public User getUser( String name) throws RemoteException ; } VIII 其中 User 的定义为,一个标准的 JavaBean Contact 定义,也是一个标准的 JavaBean 这两个类都是标准的 JavaBean: 都有默认的构造方法和符合命名规范的 getters 和setters package com.hcycom.user; public class Contact { private String phone; private String email; public Contact() { super(); } ...... getters and settters } package com.hcycom.user; public class User { private String name; private int age; private int sex; private Contact contact; public User() { super(); } ...... getters and setters } IX 生成 WSDL 文件 WSDL 是对服务的描述,比如服务的名称,能够进行的操作,和输入/输出的参数。 axis 所需的 jar 文件全都包含到 classpath 里边,然后执行如下命令 参数含义如下 ­o,­­output 指定输出的 WSDL 文件名。若没有指定,一个适当的默认 WSDL 文件名将被写到当前目录。 ­l,­­location 指定 Web 服务位置的 URL。最后的斜线或反斜线后的名字是服务端口(service port)的名字 (除非被­s 选项覆盖)。服务端口的地址位置属性被分配为该指定值。 ­P,­­portTypeName 指定 portType 元素的名字。如果未指定,则使用 class­of­portType 的名字。 ­b,­­bindingName 指定 binding 元素的名字。若未指定,使用值 –servicePortName + "SOAPBinding" 。 ­n,­­namespace 指定生成的 WSDL 的目标名称空间。 ­p,­­PkgtoNS 指定包结构到命名空间的映射。若遇到一个没有指定命名空间映射的包,则 Java2WSDL 将生成 一个适当的命名空间名。这个选项可以指定多次。 ­y,­­style 指示 WSDL 文档的风格,有 DOCUMENT, RPC 和WRAPPED 三种。默认为 RPC。 com.hcycom.user.UserManager 就是服务定义接口 执行完上述命令之后会生成一个 UserManager.wsdl 文件 (注意:­p 和后边的参数之间不能有空格,这是本人的经验) java ­cp .:$AXIS_CLASSPATH org.apache.axis.wsdl.Java2WSDL ­o UserManager.wsdl ­P UserManagerPortType ­b UserManagerSoapBinding ­l http://localhost:8080/axis/services/UserManager ­n http://www.hcycom.com/n7/User ­pcom.hcycom.user=http://www.hcycom.com/n7/User ­y rpc com.hcycom.user.UserManager X 生成服务器端和客户端代码 有了 WSDL 文件我们就可以生成服务器端和客户端的代码框架,然后再将我们具体的业务逻辑填 进去就可以了。 axis 所需的 jar 文件全都包含到 classpath 里边,执行如下命令 参数含义如下 ­s,­­server­side emit server­side bindings for web service ­p,­­package override all namespace to package mappings, use this package name instead ­c,­­implementationClassName custom name of web service implementation UserManager.wsdl 上一步产生的 wsdl 文件 执行完上述命令将产生如下文件(位于/home/xingfei/axis/com/hcycom/user) deploy.wsdd undeploy.wsdd 部署(反部署)描述符文件 Contact.java User.java 和前面自己写的一样,用哪个都可以 UserManagerPortType.java 和接口 UserManager 一样,就是名字变了。本文中用这个类。 UserManagerImpl.java 实现 UserManagerPortType 的类。具体的逻辑还得自己去填充。 UserManagerPortTypeService.java 用于获取 UserManagerPortType ,是一个接口 UserManagerPortTypeServiceLocator.java UserManagerPortTypeService 的实现 UserManagerSoapBindingStub.java 方便客户端调用服务的 Stub 类 java ­cp .:$AXIS_CLASSPATH org.apache.axis.wsdl.WSDL2Java ­s ­p com.hcycom.user ­c com.hcycom.user.UserManagerImpl UserManager.wsdl XI 实现服务 前面只是定义了服务,没有具体实现,下面要将具体实现,填入到 UserManagerImpl.java 中。因为这只是个例子,所以简单的使用一个 HashMap 来保存用户信息。具体情况下可能需要 将用户信息保存到数据库等等持久设备中。代码如下: package com.hcycom.user; import java.rmi.RemoteException; import java.util.HashMap; import java.util.Iterator; public class UserManagerImpl implements com.hcycom.user.UserManagerPortType{ private static HashMap users = new HashMap(); public synchronized int addUser(com.hcycom.user.User in0) throws RemoteException { if(users.containsKey(in0.getName())) { throw new RemoteException("user already exists"); } users.put(in0.getName(), in0); int ret = users.size(); return ret; } public synchronized int deleteUser(java.lang.String in0) throws RemoteException { if(!users.containsKey(in0)) { throw new RemoteException("user does not exist"); } users.remove(in0); int ret = users.size(); return ret; } public synchronized User[] getAllUsers() throws RemoteException { int num = users.size(); User[] userList = new User[num]; int idx = 0; for(Iterator it = users.values().iterator();it.hasNext();) userList[idx++] = (User)it.next(); return userList; } XII 这里只是示例,写的很简单。因为 web 服务是运行在多线程的情况下,实际中要注意线程安全。 部署服务 UserManager 先打开 Tomcat ,然后 axis 所需的 jar 文件全都包含到 classpath 里边,执行如下命令 得到结果 Done processing 表示部署成功 这个和前面部署是一样的,打开浏览器,访问 http://localhost:8080/axis/servlet/AxisServlet 可以看到 UserManager 服务已经成功部署,它有 4个可以调用的方法。 public synchronized User getUser(java.lang.String in0) throws RemoteException { if(!users.containsKey(in0)) { throw new RemoteException("user doen not exist"); } User user = (User)users.get(in0); return user; } } java ­cp .:$AXIS_CLASSPATH org.apache.axis.client.AdminClient /path/to/deploy.wsdd XIII 编写客户端 客户端可以用两种方式,第一是使用 AXIS 刚刚生成的 Stub,第二是使用动态调用。下面用代 码来说明。 1.使用 Stub,代码如下: import java.rmi.RemoteException; import javax.xml.rpc.ServiceException; import com.hcycom.user. *; public class UserClientUsingStub { static UserManagerPortTypeService getUserManagerPortTypeService() { return new UserManagerPortTypeServiceLocator(); } public static void main(String[] args) { UserManagerPortTypeService service = getUserManagerPortTypeService(); try { UserManagerPortType userManager = service.getUserManager(); User user = new User(); user.setAge(20); user.setName("James Gosling"); user.setSex(0); Contact contact = new Contact(); contact.setEmail("james@sun.com"); contact.setPhone("123456789"); user.setContact(contact); userManager.addUser(user); user.setAge(30); user.setName("Scott McNealy"); user.setSex(0); contact.setEmail("scott@sun.com"); contact.setPhone("987654321"); user.setContact(contact); userManager.addUser(user); User[] users = userManager.getAllUsers(); for(int i=0;i
还剩15页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 6 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

xuexxd

贡献于2013-08-14

下载需要 6 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf