本文将介绍WebService之--------Axis2准备工作的详细情况,特别是关于axis2webservice的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同
本文将介绍WebService之--------Axis2准备工作的详细情况,特别是关于axis2 webservice的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于Axis2 WebService 客户端 Axis2 调用、Axis2 WebService之会话管理(Session)、axis2实现webservice之使用services.xml文件发布WebService、axis2实现WebService之用POJO实现0配置的WebService的知识。
本文目录一览:- WebService之--------Axis2准备工作(axis2 webservice)
- Axis2 WebService 客户端 Axis2 调用
- Axis2 WebService之会话管理(Session)
- axis2实现webservice之使用services.xml文件发布WebService
- axis2实现WebService之用POJO实现0配置的WebService
WebService之--------Axis2准备工作(axis2 webservice)
Axis2的优点:支持多种语言,C,Java,C#等。
1:准备Axis2所需的jar包和War包,下载地址:
http://axis.apache.org/axis2/java/core/download.cgi
Axis2 WebService 客户端 Axis2 调用
第一 RPC 方式,不生成客户端代码
第二,document 方式,不生成客户端代码
第三,用 wsdl2java 工具,生成客户端方式调用
package samples.quickstart.client;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.rpc.client.RPCServiceClient;
import samples.quickstart.StockQuoteServiceStub;
import samples.quickstart.xsd.GetPrice;
import samples.quickstart.xsd.GetPriceResponse;
public class StockQuoteClient {
/**
* 方法一:
* 应用rpc的方式调用 这种方式就等于远程调用,
* 即通过url定位告诉远程服务器,告知方法名称,参数等, 调用远程服务,得到结果。
* 使用 org.apache.axis2.rpc.client.RPCServiceClient类调用WebService
*
【注】:
如果被调用的WebService方法有返回值 应使用 invokeBlocking 方法 该方法有三个参数
第一个参数的类型是QName对象,表示要调用的方法名;
第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];
当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。
第三个参数表示WebService方法的 返回值类型的Class对象,参数类型为Class[]。
如果被调用的WebService方法没有返回值 应使用 invokeRobust 方法
该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。
在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,
也就是 <wsdl:definitions>元素的targetNamespace属性值。
*
*/
public static void testRPCClient() {
try {
// axis1 服务端
// String url = "http://localhost:8080/StockQuote/services/StockQuoteServiceSOAP11port?wsdl";
// axis2 服务端
String url = "http://localhost:8080/axis2ServerDemo/services/StockQuoteService?wsdl";
// 使用RPC方式调用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(url);
Options options = serviceClient.getOptions();
//确定目标服务地址
options.setTo(targetEPR);
//确定调用方法
options.setAction("urn:getPrice");
/**
* 指定要调用的getPrice方法及WSDL文件的命名空间
* 如果 webservice 服务端由axis2编写
* 命名空间 不一致导致的问题
* org.apache.axis2.AxisFault: java.lang.RuntimeException: Unexpected subelement arg0
*/
QName qname = new QName("http://quickstart.samples/xsd", "getPrice");
// 指定getPrice方法的参数值
Object[] parameters = new Object[] { "13" };
// 指定getPrice方法返回值的数据类型的Class对象
Class[] returnTypes = new Class[] { double.class };
// 调用方法一 传递参数,调用服务,获取服务返回结果集
OMElement element = serviceClient.invokeBlocking(qname, parameters);
//值得注意的是,返回结果就是一段由OMElement对象封装的xml字符串。
//我们可以对之灵活应用,下面我取第一个元素值,并打印之。因为调用的方法返回一个结果
String result = element.getFirstElement().getText();
System.out.println(result);
// 调用方法二 getPrice方法并输出该方法的返回值
Object[] response = serviceClient.invokeBlocking(qname, parameters, returnTypes);
// String r = (String) response[0];
Double r = (Double) response[0];
System.out.println(r);
} catch (AxisFault e) {
e.printStackTrace();
}
}
/**
* 方法二: 应用document方式调用
* 用ducument方式应用现对繁琐而灵活。现在用的比较多。因为真正摆脱了我们不想要的耦合
*/
public static void testDocument() {
try {
// String url = "http://localhost:8080/axis2ServerDemo/services/StockQuoteService";
String url = "http://localhost:8080/StockQuote/services/StockQuoteServiceSOAP11port?wsdl";
Options options = new Options();
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(url);
options.setTo(targetEPR);
// options.setAction("urn:getPrice");
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMFactory fac = OMAbstractFactory.getOMFactory();
String tns = "http://quickstart.samples/";
// 命名空间,有时命名空间不增加没事,不过最好加上,因为有时有事,你懂的
OMNamespace omNs = fac.createOMNamespace(tns, "");
OMElement method = fac.createOMElement("getPrice", omNs);
OMElement symbol = fac.createOMElement("symbol", omNs);
// symbol.setText("1");
symbol.addChild(fac.createOMText(symbol, "Axis2 Echo String "));
method.addChild(symbol);
method.build();
OMElement result = sender.sendReceive(method);
System.out.println(result);
} catch (AxisFault axisFault) {
axisFault.printStackTrace();
}
}
/**
* 为SOAP Header构造验证信息,
* 如果你的服务端是没有验证的,那么你不用在Header中增加验证信息
*
* @param serviceClient
* @param tns 命名空间
* @param user
* @param passwrod
*/
public void addValidation(ServiceClient serviceClient, String tns , String user, String passwrod) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(tns, "nsl");
OMElement header = fac.createOMElement("AuthenticationToken", omNs);
OMElement ome_user = fac.createOMElement("Username", omNs);
OMElement ome_pass = fac.createOMElement("Password", omNs);
ome_user.setText(user);
ome_pass.setText(passwrod);
header.addChild(ome_user);
header.addChild(ome_pass);
serviceClient.addHeader(header);
}
/**
* 方法三:利用axis2插件生成客户端方式调用
*
*/
public static void testCodeClient() {
try {
String url = "http://localhost:8080/axis2ServerDemo/services/StockQuoteService";
StockQuoteServiceStub stub = new StockQuoteServiceStub(url);
GetPrice request = new GetPrice();
request.setSymbol("ABCD");
GetPriceResponse response = stub.getPrice(request);
System.out.println(response.get_return());
} catch (org.apache.axis2.AxisFault e) {
e.printStackTrace();
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
StockQuoteClient.testRPCClient();
// StockQuoteClient.testDocument();
// StockQuoteClient.testCodeClient();
}
}
wsdl2java 用于根据 WSDL 生成相应的服务端和客户端代码的生成工具。
命令行格式为:WSDL2Java [options] -uri <url or path> : A url or path to a WSDL
例如:
wsdl2java -uri http://localhost:8080/cxfService_0617/services/Hellows?wsdl -s -o build\client
其中常用的 options 具体如下:
-o <path> : 指定生成代码的输出路径
-a : 生成异步模式的代码
-s : 生成同步模式的代码
-p <pkg> : 指定代码的 package 名称
-l <languange> : 使用的语言 (Java/C) 默认是 java
-t : 为代码生成测试用例
-ss : 生成服务端代码 默认不生成
-sd : 生成服务描述文件 services.xml, 仅与 - ss 一同使用
-d <databinding> : 指定 databingding,例如,adb,xmlbean,jibx,jaxme and jaxbri
-g : 生成服务端和客户端的代码
-pn <port_name> : 当 WSDL 中有多个 port 时,指定其中一个 port
-sn <serv_name> : 选择 WSDL 中的一个 service
-u : 展开 data-binding 的类
-r <path> : 为代码生成指定一个 repository
-ssi : 为服务端实现代码生成接口类
-S : 为生成的源码指定存储路径
-R : 为生成的 resources 指定存储路径
–noBuildXML : 输出中不生成 build.xml 文件
–noWSDL : 在 resources 目录中不生成 WSDL 文件
–noMessageReceiver : 不生成 MessageReceiver 类
Axis2 WebService之会话管理(Session)
首先保证你已配置好Axis2。
实现同一个WebService的Session管理需要如下三步:
1. 使用MessageContext和ServiceContext获得与设置key-value对。
2. 为要进行Session管理的WebService类所对应的<service>元素添加一个scope属性,并将该属性值设为transportsession。
3. 在客户端使用setManageSession(true)打开Session管理功能。
下面是一个在同一个WebService类中管理Session的例子
在Eclipse中新建一个webservice工程,如命名为:SessionWebService,建立一个
{
{
{
ServiceContext sc = mc.getServiceContext();
sc.setProperty("login", "
}
{
}
}
{
ServiceContext sc = mc.getServiceContext();
}
}
在
下面是
登录服务
service.LoginService
class
在
java.lang.String targetEndpoint,
{
_serviceClient.getoptions().setSoapVersionURI(
org.apache.axiom.soap.soAP12Constants.soAP_ENVELOPE_NAMESPACE_URI);
}
下面的客户端代码使用
package test;
import client.LoginServiceStub;
public class TestClient
{
public static void main(String[] args)
{
try
{
LoginServiceStub stub = new LoginServiceStub();
LoginServiceStub.Login login = new LoginServiceStub.Login();
login.setUsername("bill");
login.setPassword("1234");
if(stub.login(login).local_return)
{
System.out.println(stub.getLoginMsg().local_return);
}
}
catch (Exception e)
{
e.printstacktrace();
}
}
}
axis2实现webservice之使用services.xml文件发布WebService
还是对教程的延伸,本来是周五要写的,但是耽搁了一下,就拖到周一了。
用Axis2实现Web Service,虽然可以将POJO类放在axis2\WEB-INF\pojo目录中直接发布成Web Service,这样做不需要进行任何配置,但这些POJO类不能在任何包中。这似乎有些不方便,为此,Axis2也允许将带包的POJO类发布成Web Service。
先实现一个POJO类,代码如下:
这个类有两个方法,这两个方法都需要发布成Web Service方法。这种方式和直接放在pojo目录中的POJO类不同。要想将MyService类发布成Web Service,需要一个services.xml文件,这个文件需要放在meta-inf目录中,该文件的内容如下:
其中<service>元素用于发布Web Service,一个<service>元素只能发布一个WebService类,name属性表示WebService名,如下面的URL可以获得这个WebService的WSDL内容:
http://localhost:8080/axis2/services/myService?wsdl (这个得等到.aar文件出来之后)
其中name属性名就是上面URL中"?"和"/"之间的部分。
<description>元素表示当前Web Service的描述,<parameter>元素用于设置WebService的参数,在这里用于设置WebService对应的类名。在这里最值得注意的是<messageReceivers>元素,该元素用于设置处理WebService方法的处理器。例如,getGreeting方法有一个返回值,因此,需要使用可处理输入输出的RPcmessageReceiver类,而update方法没有返回值,因此,需要使用只能处理输入的RPCInOnlyMessageReceiver类。
使用这种方式发布WebService,必须打包成.aar文件,..aar文件实际上就是改变了扩展名的.jar文件。在现在建立了两个文件(这两个文件夹任意):MyService.java和services.xml。将MyService.java编译,生成MyService.class。services.xml和MyService.class文件的位置如下:
D:\ws\service\MyService.class
D:\ws\meta-inf\services.xml
在windows控制台中进入ws目录,并输入如下的命令生成.aar文件(实际上,.jar文件也可以发布webservice,但axis2官方文档中建议使用.aar文件发布webservice):
jar cvf ws.aar . jar cvf AxisTest.aar .
如下是我测试的过程
原来发现不管要.aar,之后还需要一个“.”,即.arr.,但是最坑爹的就是这里了,加了“.”之后还是不对啊,最后的问题居然是这个后面的点要空一格,不能紧挨着.arr
如下成功之后的文件夹情况
最后将ws.aar文件复制到<Tomcat安装目录>\webapps\axis2\WEB-INF\services目录中,启动Tomcat后,就可以调用这个WebService了。
已经显示webservice发布成功了,接下来就是编写客户端进行调运了,跟前面一样,也需要wsdl2java命令去生成stub类,过程我就不多说了,之前的博客里有
如下是调用客户端的代码
运行结果
由于“帅哥”是在服务器端打印的,所以客户端是看不到的。
在打包arr文件的时候,发现有一个build.xml文件,这个是ant脚本中的知识,在本题中暂时不涉及,以后再介绍。
如果想发布多个WebService,可以使用<serviceGroup>元素,如再建立一个MyService1类,代码如下:
在services.xml文件中可以使用如下的配置代码来配置MyService和MyService1类:
axis2实现WebService之用POJO实现0配置的WebService
参照着网上的教程,自己做了一遍,发现教程是错误百出啊,搞得我弄了一个下午才搞好,废话少说,看招!
一、Axis2的下载和安装
读者可以从如下的网址下载Axis2的最新版本:
http://ws.apache.org/axis2/
在本文使用了目前Axis2的最新版本1.6.2。读者可以下载如下两个zip包:
axis2-1.4.1-bin.zip f3d04032c142898c206a1312d8385d9a
axis2-1.4.1-war.zip 51a77ec0a47483cdfd8166797bdc977e
其中axis2-1.6.2-bin.zip文件中包含了Axis2中所有的jar文件,axis2-1.6.2-war.zip文件用于将WebService发布到Web容器中。
将axis2-1.6.2-war.zip文件解压到相应的目录,将目录中的axis2.war文件放到<Tomcat安装目录>\webapps目录中(本文使用的Tomcat的版本是6.x),并启动Tomcat。
在浏览器地址栏中输入如下的URL:
http://localhost:8080/axis2/
如果在浏览器中显示出如图1所示的页面,则表示Axis2安装成功。
二、编写和发布WebService
对于用Java实现的服务程序给人的印象就是需要进行大量的配置,不过这一点在Axis2中将被终结。在Axis2中不需要进行任何的配置,就可以直接将一个简单的POJO发布成WebService。其中POJO中所有的public方法将被发布成WebService方法。
下面我们来实现一个简单的POJO,代码如下:
在SimpleService类中有两个方法,由于这两个方法都是public方法,因此,它们都将作为WebService方法被发布。
编译SimpleService类后,将SimpleService.class文件放到<Tomcat安装目录>\webapps\axis2\WEB-INF\pojo目录中(如果没有pojo目录,则建立该目录)。现在我们已经成功将SimpleService类发布成了WebService。在浏览器地址栏中输入如下的URL:
http://localhost:8080/axis2/services/listServices
这时当前页面将显示所有在Axis2中发布的WebService,如图2所示。
在浏览器地址栏中输入如下的两个URL来分别测试getGreeting和getPrice方法:
http://localhost:8080/axis2/services/SimpleService/getGreeting?name=bill
http://localhost:8080/axis2/services/SimpleService/getPrice
图3和图4分别显示了getGreeting和getPrice方法的测试结果。
在编写、发布和测试0配置的WebService时应注意如下几点:
1. POJO类不能使用package关键字声明包。
2. Axis2在默认情况下可以热发布WebService,也就是说,将WebService的.class文件复制到pojo目录中时,Tomcat不需要重新启动就可以自动发布WebService。如果想取消Axis2的热发布功能,可以打开<Tomcat安装目录>\webapps\axis2\WEB-INF\conf\axis2.xml,找到如下的配置代码:
<parameter name="hotdeployment">true</parameter>
将true改为false即可。要注意的是,Axis2在默认情况下虽然是热发布,但并不是热更新,也就是说,一旦成功发布了WebService,再想更新该WebService,就必须重启Tomcat。这对于开发人员调试WebService非常不方便,因此,在开发WebService时,可以将Axis2设为热更新。在axis2.xml文件中找到<parameter name="hotupdate">false</parameter>,将false改为true即可。
3. 在浏览器中测试WebService时,如果WebService方法有参数,需要使用URL的请求参数来指定该WebService方法参数的值,请求参数名与方法参数名要一致,例如,要测试getGreeting方法,请求参数名应为name,如上面的URL所示。
4. 发布WebService的pojo目录只是默认的,如果读者想在其他的目录发布WebService,可以打开axis2.xml文件,并在<axisconfig>元素中添加如下的子元素:
<deployer extension=".class" directory="my" class="org.apache.axis2.deployment.POJODeployer"/>
上面的配置允许在<Tomcat安装目录>\webapps\axis2\WEB-INF\my目录中发布WebService。例如,将本例中的SimpleService.class复制到my目录中也可以成功发布(但要删除pojo目录中的SimpleService.class,否则WebService会重名)。
三、 用Java实现调用WebService的客户端程序
WebService是为程序服务的,只在浏览器中访问WebService是没有意义的。因此,在本节使用Java实现了一个控制台程序来调用上一节发布的WebService。调用WebService的客户端代码如下:
运行上面的程序后,将在控制台输出如下的信息:
你好 超人
443
在编写客户端代码时应注意如下几点:
1. 客户端代码需要引用很多Axis2的jar包,如果读者不太清楚要引用哪个jar包,可以在Eclipse的工程中引用Axis2发行包的lib目录中的所有jar包。
2. 在本例中使用了RPCServiceClient类的invokeBlocking方法调用了WebService中的方法。invokeBlocking方法有三个参数,其中第一个参数的类型是QName对象,表示要调用的方法名;第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。
3. 如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法,该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。
4. 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:deFinitions>元素的targetNamespace属性值,下面是SimpleService类生成的WSDL文件的代码片段:
四、用wsdl2java简化客户端的编写
也许有很多读者会说“有没有搞错啊,只调用两个WebService方法用要写这么多代码,太麻烦了”。
不过幸好Axis2提供了一个wsdl2java.bat命令可以根据WSDL文件自动产生调用WebService的代码。wsdl2java.bat命令可以在<Axis2安装目录>"bin目录中找到。在使用wsdl2java.bat命令之前需要设置AXIS2_HOME环境变量,该变量值是<Axis2安装目录>。需要注意的是你首先得把jdk的系统变量配置好,因为我们一旦都是在eclipse中开发java程序的,不需要配置jdk的系统变量,一上来就配置axis2的系统变量肯定会找不到jdk的,需要注意的是安装jdk是把jdk和jre要安装在不同的文件夹下面,不然在配置classpath是就会找不到几个jar文件。axis2的系统变量配置与jdk的相同,再次就不在说了,jdk测试的时候可以用javac -version,axis2测试的时候可以用wsdl2java。
把已经生成的wsdl文件转换成java文件的话,就需要在doc敲命令,命令就不介绍了,百度一下就可以了,这里需要强调的是uri而不是url,即使这个错误搞得我浪费了一小时的时间,也不知道当初制定这个命令的人是怎么想的,太坑爹了。更不爽的是,生成的java文件不知道去哪了,搞得我还得搜一下。
其实这是我的错误,明明人家已经是在当前目录下了,我还没注意到,哎,专业意识需要提高了
这不是清清楚楚的写着C………………吗,我太坑爹了,生成的这个stub类我就不贴出来了,实在是太多了,看了一下有2275行,太恐怖了,不知道为什么会这么多,看来就简洁程度而言,还是xml文件简洁哈。
l 其中-url参数指定了wsdl文件的路径,可以是本地路径,也可以是网络路径。-p参数指定了生成的Java类的包名,-o参数指定了生成的一系列文件保存的根目录。在执行完上面的命令后,读者就会发现在当前目录下多了个stub目录,在."stub"src"client目录可以找到一个SimpleServiceStub.java文件,该文件复杂调用WebService,读者可以在程序中直接使用这个类,代码如下:
package client;
public class StubClient { public static void main(String[] args) throws Exception { SimpleServiceStub stub = new SimpleServiceStub(); SimpleServiceStub.GetGreeting gg = new SimpleServiceStub.GetGreeting(); SimpleServiceStub.GetPrice gp = new SimpleServiceStub.GetPrice(); gg.setName("比尔"); System.out.println( stub.getGreeting(gg).get_return()); System.out.println(stub.getPrice(gp).get_return()); }
}
上面的代码大大简化了调用WebService的步骤,并使代码更加简洁。但要注意的是,wsdl2java.bat命令生成的Stub类将WebService方法的参数都封装在了相应的类中,类名为方法名,例如,getGreeting方法的参数都封装在了GetGreeting类中,要想调用getGreeting方法,必须先创建GetGreeting类的对象实例。
这就是今天下午的劳动成果了,虽说是照着教程做的,但是起码我发现了教程的好多错误,自己也从中学到了不少的东西。
下班了,做梦去!明天继续!
今天关于WebService之--------Axis2准备工作和axis2 webservice的讲解已经结束,谢谢您的阅读,如果想了解更多关于Axis2 WebService 客户端 Axis2 调用、Axis2 WebService之会话管理(Session)、axis2实现webservice之使用services.xml文件发布WebService、axis2实现WebService之用POJO实现0配置的WebService的相关知识,请在本站搜索。
本文标签: