2008年1月24日星期四

WebService_103:Axis介绍

【Axis】:Apache EXtensible Interaction System,a fancy way of implying it's a very configurable SOAP engine。
我们可以通过Axis学习JAX-RPC,因为Axis完全实现了JAX-RPC 和SAAJ(jaxrpc.jar 和saaj.jar) 。
如何使用Axis?
1. 实验准备
(1)下载Axis1.4
http://ws.apache.org/axis/
(2)下载Tomcat5.5
http://tomcat.apache.org/download-55.cgi

2. 安装Axis1.4
(1)解压缩axis-bin-1_4.zip后,复制axis-1_4\webapps\axis到apache-tomcat-5.5.26\webapps下。
(2)启动tomcat:catalina run。
(3)访问
http://127.0.0.1:8080/axis/,点击Validation,会有信息提示。
(4)按照信息提示,分别加入activation.jar、mail.jar、xmlsec.jar(我用的是xmlsec-1.4.2.jar)到webapps\axis\lib下。
确认没有任何错误或警告信息后,就说明Axis1.4安装成功。

3. 开发Web服务 from a Java Interface
(1)写一个Java Interface,并编译成类。
package com.javaneverdie;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloDBWebService extends Remote {
public String hello(String str) throws RemoteException;
}

(2)使用Java2WSDL创建WSDL
java org.apache.axis.wsdl.Java2WSDL [options] class-of-portType。比如:
java org.apache.axis.wsdl.Java2WSDL -o HelloDBWebService.wsdl
-l"http://localhost:8080/axis/services/HelloDB" -n http://javanerverdie.com/
-p"com.javaneverdie" "http://javaneverdie.com" com.javaneverdie.HelloDBWebService -y DOCUMENT -u LITERAL

其中:
-o 输出的WSDL文件名称。
-l 指向服务的地址。
-n WSDL的目标名称空间。
-p package到namespace的mapping,可能有多个。
-y style of the binding (DOCUMENT,RPC,WRAPPED)。
-u use of the binding(LITERAL,ENCODED)

(3)使用WSDL2Java创建Bindings
java org.apache.axis.wsdl.WSDL2Java [options] WSDL-URI。比如:
java org.apache.axis.wsdl.WSDL2Java -o C:\Output -s -d Session -S true HelloDBWebService.wsdl

其中:
-o 输出目录。
-s emit server-side bindings for web service。
-d add scope to deploy.wsdd: "Application","Request", "Session"。
-N namespace到package的mapping。
-S deploy skeleton (true) or implementation (false) in deploy.wsdd. Default is false. Assumes server-side.

以下文件将被产生:
· HelloDBSoapBindingImpl.java:默认的服务实现,你应该修改成自己想要的实现。
· HelloDBService.java:新的Interface,包括java.rmi.Remote。
· HelloDBWebServiceService.java:客户端服务Interface。
· HelloDBWebServiceServiceLocator.java:客户端服务实现。
· HelloDBSoapBindingSkeleton.java:服务端skeleton。
· HelloDBSoapBindingStub.java:客户端stub。
· deploy.wsdd:Deployment descriptor。
· undeploy.wsdd:Undeployment descriptor。

(4)编译产生的java文件,把class复制到webapps\axis\WEB-INF\classes\下。

(5)发布/卸载 Web服务
java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd
java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService undeploy.wsdd
访问
http://127.0.0.1:8080/axis/servlet/AxisServlet,确认已经成功发布。

(6)测试 Web服务:使用JAX-RPC 3种客户端调用

package com.javaneverdie.test;

import java.net.*;
import javax.xml.rpc.*;
import javax.xml.namespace.*;

import com.javaneverdie.*;

public class HelloDBTest {
public static void main(String[] args) {
try {
// 1. Statically Generated Stubs
System.out.println(new HelloDBWebServiceServiceLocator().getHelloDB().hello("Ping Ma"));

// 2. Dynamic Invocation Using the Service Interface
// Create a service class with WSDL information.
String wsdlUrl = "http://127.0.0.1:8080/axis/services/HelloDB?wsdl";
String nameSpaceUri = "http://javaneverdie.com";
String serviceName = "HelloDBWebServiceService";
String portName = "HelloDB";
ServiceFactory serviceFactory1 = ServiceFactory.newInstance();
Service service1 = serviceFactory1.createService(new URL(wsdlUrl), new QName(nameSpaceUri, serviceName));
HelloDBWebService proxy = (HelloDBWebService)service1.getPort(new QName(nameSpaceUri, portName), HelloDBWebService.class);
System.out.println(proxy.hello("Ping Ma"));

// 3. Dynamic Invocation Interface (DII)
// Create a service class with no WSDL information. You still must know something about the WSDL, however: the service's name.
String endpoint = "http://127.0.0.1:8080/axis/services/HelloDB";
ServiceFactory serviceFactory2 = ServiceFactory.newInstance();
Service service2 = serviceFactory2.createService(new QName(nameSpaceUri, serviceName));
Call call = (Call)service2.createCall();
call.setOperationName(new QName("http://javaneverdie.com", "hello")); call.setTargetEndpointAddress(endpoint);
String ret = (String)call.invoke(new Object[] { "Ping Ma" });
System.out.println(ret);
} catch (Exception e) {
e.printStackTrace();
}
}
}

注:使用DII方式调用时,抛出异常:org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.网上有很多人遇到这个问题,尚未找到答案。
Axis架构
理解WSDD(Web Service Deployment Descriptor)

没有评论: