您的位置:首页 > 运维架构 > Apache

利用Apache Axis开发JAX-RPC服务

2013-01-02 10:32 489 查看
JAX-RPC(Java API for XML-based RPC)是早期的Java Web Services的规范,它经历了1.0和1.1版本,其2.0版本被更名为JAX-WS 2.0.

本文重点讲解如何利用Apache Axis (JAX-RPC的实现)来开发JAX-RPC服务。

开发一个JAX-RPC服务主要分成服务端和客户端。

1 服务端

服务端的创建方法有两种

1.1 Top-Down方法

先创建wsdl文件,再利用CMD生成相应的Java代码。这种方法也翻译作“契约优先”方法。在本文中我们不做介绍。

1.2 Botton-Up方法

先创建Java代码,再利用CMD生成相应的Wsdl或其他组件。这种方法也翻译作“代码优先”方法。我们重点介绍这种方式。

有三种方式来在Axis中发布一个JAX-RPC服务:JWS方法WSDD方法高级方法

1.2.1 JWS方法

1.2.1.1 创建Java代码

我们新建一个项目jaxrpc_server_java_jws



服务的代码很简单

package org.pfyu.service.services;

public class MySrv {

public String sayHello(String p){
return("hello: "+p);
}

}


1.2.1.2 发布Web服务

将MySrv.java拷贝出来,并更名为MySrv.jws,把这个文件扔到TOMCAT_HOME/webapps/axis/目录中



启动Tomcat服务器,访问http://localhost:8080/axis/MySrv.jws?wsdl,就可以看到该Web服务对应的WSDL内容。

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://localhost:8080/axis/MySrv.jws" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost:8080/axis/MySrv.jws" xmlns:intf="http://localhost:8080/axis/MySrv.jws" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<wsdl:message name="sayHelloRequest">
<wsdl:part name="p" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="sayHelloResponse">
<wsdl:part name="sayHelloReturn" type="xsd:string"/>
</wsdl:message>
<wsdl:portType name="MySrv">
<wsdl:operation name="sayHello" parameterOrder="p">
<wsdl:input message="impl:sayHelloRequest" name="sayHelloRequest"/>
<wsdl:output message="impl:sayHelloResponse" name="sayHelloResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MySrvSoapBinding" type="impl:MySrv">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="sayHelloRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://DefaultNamespace" use="encoded"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/axis/MySrv.jws" use="encoded"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MySrvService">
<wsdl:port binding="impl:MySrvSoapBinding" name="MySrv">
<wsdlsoap:address location="http://9.123.158.35:8080/axis/MySrv.jws"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
OK,到此位置,一个JAX-RPC服务就发布成功了。当然,我们可以利用java2wsdl工具来显示生成wsdl文件,这个待会会介绍。

1.2.2 WSDD方法

可以看出,JWS的方法是有很多局限性的,比如说需要服务实现的源代码,另外源代码不能有包名,等等。因此,一般我们会推荐使用WSDD的发布方法。WSDD是Axis Web Service Deployment Descriptor (WSDD)的简称,是一种相对高级的Web服务发布方式。

1.2.2.1 创建Java代码

我们新建一个项目jaxrpc_server_java_wsdd



服务的实现代码和前面的一样。在这里我们编写了deploy.wsdd和undeploy.wsdd,可以看一下源代码很简单:

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="MySrv" provider="java:RPC">
<parameter name="className" value="org.pfyu.service.services.MySrv"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
<service name="MySrv"/>
</undeployment>


1.2.2.2 发布Web服务

将编译过的MySrv.class以及deploy.wsdd、undeploy.wsdd一起拷贝到TOMCAT_HOME/webapps/axis/WEB-INF/classes目录中(wsdd文件其实位置并没有讲究)。接下来我们运行AdminClient工具来发布Web服务,在这之前,一定要启动Tomcat服务器并且最好监听8080端口。

现在开始运行AdminClient。

C:\Software\Application Server\Tomcat\apache-tomcat-6.0.28\webapps\axis\WEB-INF>java -cp %AXIS_CLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd

Processing file deploy.wsdd

<Admin>Done processing</Admin>

注意AXIS_CLASSPATH是Windows下设置的环境变量,将axis/lib下的所有jar包都加进去了,除此之外,还加入了activation.jar和mail.jar来避免一些不必要的错误。

运行AdminClient后,会将我们实现的服务MySrv注册到TOMCAT_HOME/webapps/axis/WEB-INF/server-config.wsdd(如果没有该文件,则自动生成一个)中:

<service name="MySrv" provider="java:RPC">

<parameter name="allowedMethods" value="*"/>

<parameter name="className" value="org.pfyu.service.services.MySrv"/>

</service>

好了,一个Web服务就发布成功了,我们可以在浏览器查看对应的WSDL内容:http://9.123.158.35:8080/axis/services/MySrv?wsdl

1.2.3 高级方法

可以看出,即使是WSDD方法也存在着局限性,最大的弊端是需要将我们自定义的服务实现和Axis的Web应用掺杂在一起,不太利于代码的维护。在高级方法里,我们将介绍如何采用“拿来主义”,即将Axis的运行时插入到我们自己的Web应用程序中。

1.2.3.1 创建Java代码

我们新建一个项目jaxrpc_server_tomcat_advanced



这里,我们是利用IDE工具来生成上图所示的项目结构。但是,我们可以了解一下这个个项目结构里的内容:

这是一个以Tomcat为server runtime的Web项目。

首先,需要把AXIS/LIb下面的Jar包拷贝到WEB-INF/lib目录下。

其次,编写deploy.wsdd和undeploy.wsdd文件。

最后,在WEB-INF下面创建server-config.wsdd文件,并注册创建的服务。

1.2.3.2 发布Web服务

这种发布方式相对简单,只需要把该Web应用部署到应用服务器上即可。一切就绪后,我们可以通过浏览器来访问相应的wsdl内容。http://localhost:8080/jaxrpc_server_tomcat_advanced/services/MySrv?wsdl,注意URL和以前比有什么变化没有?

2. 客户端

基于Axis的JAX-RPC服务的调用方式通常有三种:Dynamic Invocation Interface (DII)Dynamic Proxy,和Generated Stub。我们来逐一介绍:

2.1 Dynamic Invocation Interface (DII)

这种方式我们需要对WSDL和SOAP有所理解,这里是一个示例:

package org.pfyu.service.client;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class MySrvClient {

/**
* @param args
* @throws MalformedURLException
* @throws ServiceException
* @throws RemoteException
*/
public static void main(String[] args) throws MalformedURLException, ServiceException, RemoteException {
URL endpointAddress = new URL("http://localhost:8080/jaxrpc_server_tomcat_advanced/services/MySrv");

Service service = new Service();
Call call = (Call)service.createCall();

call.setTargetEndpointAddress(endpointAddress);
call.setOperationName(new QName("http://services.service.pfyu.org","sayHello"));

String retValue = (String)call.invoke(new Object[]{"pfyu"});

System.out.println(retValue);
}

}


2.2 Dynamic Proxy

这种方式相对简单,不需要我们深入了解WSDL和SOAP。这是一个示例:

package org.pfyu.service.client;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.ServiceFactory;

import org.pfyu.service.interfaces.MySrvSEI;

public class MySrvClient {

/**
* @param args
* @throws MalformedURLException
* @throws ServiceException
* @throws RemoteException
*/
public static void main(String[] args) throws ServiceException, MalformedURLException, RemoteException {
ServiceFactory factory = ServiceFactory.newInstance();

String wsdlURL = "http://localhost:8080/jaxrpc_server_tomcat_advanced/services/MySrv?wsdl";
String nameSpace = "http://services.service.pfyu.org";
String serviceName = "MySrvService";
String portName = "MySrv";
Service service = factory.createService(new URL(wsdlURL),new QName(nameSpace,serviceName));

MySrvSEI dynamicProxy = (MySrvSEI) service.getPort(new QName(nameSpace,portName), MySrvSEI.class);

String retValue = dynamicProxy.sayHello("pfyu");

System.out.println(retValue);
}

}


2.3 Generated Stub

这种方式和Dynamic Proxy相似,也不需要我们对WSDL和SOAP深入了解。我们首先要利用WSDL2JAVA工具来生成相应的存根(STUB),然后编写客户端程序来调用这些STUB。WSDL2JAVA的用法如下:

Usage: java org.apache.axis.wsdl.WSDL2Java [options] WSDL-URI

Options:

-h, --help
print this message and exit
-v, --verbose
print informational messages
-n, --noImports
only generate code for the immediate WSDL document
-O, --timeout <argument>
timeout in seconds (default is 45, specify -1 to disable)
-D, --Debug
print debug information
-W, --noWrapped
turn off support for "wrapped" document/literal
-s, --server-side
emit server-side bindings for web service
-S, --skeletonDeploy <argument>
deploy skeleton (true) or implementation (false) in
deploy.wsdd.
Default is false.  Assumes --server-side.
-N, --NStoPkg <argument>=<value>
mapping of namespace to package
-f, --fileNStoPkg <argument>
file of NStoPkg mappings (default NStoPkg.properties)
-p, --package <argument>
override all namespace to package mappings, use this package
name instead
-o, --output <argument>
output directory for emitted files
-d, --deployScope <argument>
add scope to deploy.xml: "Application", "Request", "Session"
-t, --testCase
emit junit testcase class for web service
-a, --all
generate code for all elements, even unreferenced ones
-T, --typeMappingVersion
indicate 1.1 or 1.2. The default is 1.1 (SOAP 1.1 JAX-RPC  compliant.
1.2 indicates SOAP 1.1 encoded.)
-F, --factory <argument>
name of a custom class that implements GeneratorFactory interface
(for extending Java generation functions)
-i, --nsInclude <namespace>
namescape to specifically include in the generated code (defaults to
all namespaces unless specifically excluded with the -x option)
-x, --nsExclude <namespace>
namespace to specifically exclude from the generated code (defaults to
none excluded until first namespace included with -i option)
-p, --property <name>=<value>
name and value of a property for use by the custom GeneratorFactory
-H, --helperGen
emits separate Helper classes for meta data
-U, --user <argument>
username to access the WSDL-URI
-P, --password <argument>
password to access the WSDL-URI
-c, --implementationClassName <argument>
use this as the implementation class


OK,我们开始运行命令来生成Stub:

D:\WORK\Project\ServiceInvest\JAXRPC\workspace_rad\jaxrpc_client_java_generatedstub>java -cp %AXIS_CLASSPATH% org.apache.axis.wsdl.WSDL2Java -o src http://localhost:8080/jaxrpc_server_tomcat_advanced/services/MySrv?wsdl 结果,在项目的src目录下生成了如下文件:

/jaxrpc_client_java_generatedstub/src/org/pfyu/service/services/MySrv.java

/jaxrpc_client_java_generatedstub/src/org/pfyu/service/services/MySrvService.java

/jaxrpc_client_java_generatedstub/src/org/pfyu/service/services/MySrvServiceLocator.java

/jaxrpc_client_java_generatedstub/src/org/pfyu/service/services/MySrvSoapBindingStub.java

最后,我们来调用这些Stub,以下是示例:

package org.pfyu.service.client;

import java.net.MalformedURLException;
import java.rmi.RemoteException;

import javax.xml.rpc.ServiceException;

import org.pfyu.service.services.MySrv;
import org.pfyu.service.services.MySrvService;
import org.pfyu.service.services.MySrvServiceLocator;

public class MySrvClient {

/**
* @param args
* @throws MalformedURLException
* @throws ServiceException
* @throws RemoteException
*/
public static void main(String[] args) throws ServiceException, RemoteException{
MySrvService service = new MySrvServiceLocator();
MySrv port = service.getMySrv();

String retValue = port.sayHello("pfyu");
System.out.println(retValue);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: