网上关于axis2做webservice的中文文章并不多
axis2确实和axis1有很大不同
其中返回自定义对象的方法似乎就不兼容(可能仅仅是我还没研究出来), axis1返回对象或对象列表可以直接在方法返回类型中写明, serverlet会自动翻译成wsdl, 虽然axis2也可以自动翻译, 但是用过的客户端生成工具都没法直接使用此服务, 最后都归于"到OMElemet 对象无法转换", 所以我的方法只好自己写转换函数, 我想这个应该不是axis2的标准方法吧, 怎么会越来越麻烦?
下面讲一下我的使用流程
需求: 做个webservice服务, 从数据库里面读取flightleg的一个列表并返回, flightleg列表可以认为是经过一个select语句返回的记录集合
软件环境, windows xp sp2, tomcat5.5 for windows 单一安装版, jre1.5(tomcat5.5的需要), axis2-0.95(当时是最新版)
试验流程:
直接安装 tomcat5.5 for windows , 发现服务总是在启动之后马上自己关闭, 查找原因, 发现原来自己用的都是jre1.4, 后从别地拷贝一个jre_1.5目录到Program Files\j2sdk1.4.2_05中, 然后设置tomcat的 java virtual machine 为Program Files\j2sdk1.4.2_05\jre_1.5\bin\client\jvm.dll , 即可正常启动.
axis2安装, 这个网上介绍的很多, 也很容易, 就下载那个axis2.war包, 拷贝到Program Files\Apache Software Foundation\Tomcat 5.5\webapps\目录中, 就算发布了, tomcat自动感知, 并生成axis2这个目录结构. 进入http://localhost:8080/axis2/ 可以看到欢迎页面, 然后点击Services 可以看到几个示范serviece, 具体怎么使用就不多说了, 网上不少, 自带的doc也有说明.
编写service程序, 后面逻辑就不管了, 关键要编写个serviceproxy类, 并在里面暴露方法作为webserivce调用, sample里面也有很多, 但是至今还没看到返回自定义对象的. 我写的如下:
public
OMElement getPVGFlightLegs()
{
List list
=
null
;
InquiryEngine engine
=
InquiryFactory.getInquiryEngine();
list
=
(List)engine.getPVGFlightLegs();
OMElement ele
=
null
;
ele
=
createOMElementFromList(list);
return
ele;
}
返回的是OMElement 统一对象, 需要自己构造OMElement对象树并返回, createOMElementFromList() 代码如下:
public OMElement createOMElementFromList(List flightLegInfoList)
{
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://localhost:8080/axis2/services/FidsService", "fids");
OMElement resp = fac.createOMElement("flightLeglist", omNs);
for(Iterator it = flightLegInfoList.iterator(); it.hasNext(); )
{
FlightLegInfo flightLegInfo = (FlightLegInfo)it.next();
OMElement record = fac.createOMElement("record", omNs);
OMElement flightNoElement = fac.createOMElement("flightNo", omNs);
OMElement tailNoElement = fac.createOMElement("tailNo", omNs);
flightNoElement.addChild(fac.createText(flightNoElement, flightLegInfo.getFlightNo()));
tailNoElement.addChild(fac.createText(tailNoElement, flightLegInfo.getTailNo()));
record.addChild(flightNoElement);
record.addChild(tailNoElement);
resp.addChild(record);
}
return resp;
}
代码的含义是返回包含flightNo和tailNo的record列表, 构造成XML树.
web-inf\services.xml 如下:
<
service
name
="FidsService"
>
<
description
>
This is a fids web service.
</
description
>
<
parameter
name
="ServiceClass"
locked
="false"
>
com.cea2.service.fids.ServiceProxy
</
parameter
>
<
operation
name
="getPVGFlightLegs"
>
<
messageReceiver
class
="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"
/>
</
operation
>
</
service
>
然后把所有的class,lib,web-inf\services.xml 等组织起来,打个jar包, 并改后缀为aar (这个过程有个eclipse插件Axis2_Service_Archiver可以完成这个过程, 但不太会用, 还事先需要.wsdl文件??), 并拷贝到Program Files\Apache Software Foundation\Tomcat 5.5\webapps\axis2\WEB-INF\services\中. 然后重启tomcat, 进入http://localhost:8080/axis2/ 看services, 里面有FidsService, 点击可以看到wsdl, 服务端算成功大半了.
客户端: 在做返回自定义对象的时候, 用了几个eclipse自动生成工具, 甚至还用了axis2自带命令行wsdl2java, 都不行. 改为返回OMElement的时候, 就干脆没有用gererator, 直接写了testClient类, 并把service端中的FlightLegInfo(对应单条记录对象)拷贝过来. testClient如下
package
test;
import
org.apache.axis2.AxisFault;
import
org.apache.axis2.Constants;
import
org.apache.axis2.addressing.EndpointReference;
import
org.apache.axis2.client.Options;
import
org.apache.axis2.client.ServiceClient;
import
org.apache.ws.commons.om.OMElement;
import
org.apache.ws.commons.om.OMNode;
import
javax.xml.stream.XMLOutputFactory;
import
javax.xml.stream.XMLStreamException;
import
java.io.StringWriter;
import
java.util.ArrayList;
import
java.util.Iterator;
import
java.util.List;
/** */
/**
* Sample for synchronous single channel blocking service invocation.
* Message Exchage Pattern IN-OUT
*/
public
class
testClient
{
private
static
EndpointReference targetEPR
=
new
EndpointReference(
"
http://localhost:8080/axis2/services/FidsService
"
);
public
static
void
main(String args[])
{
try
{
OMElement payload
=
ClientUtil.getEchoOMElement();
Options options
=
new
Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
options.setAction(
"
getPVGFlightLegs
"
);
//
Blocking invocation
ServiceClient sender
=
new
ServiceClient();
sender.setOptions(options);
OMElement result
=
sender.sendReceive(payload);
//
显示xml
StringWriter writer
=
new
StringWriter();
result.serialize(XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer));
writer.flush();
System.out.println(writer.toString());
//
System.out.println("first:");
//
结果转换为list
List list
=
getResults(result);
}
catch
(AxisFault axisFault)
{
axisFault.printStackTrace();
}
catch
(XMLStreamException e)
{
e.printStackTrace();
}
}
private
static
List getResults(OMElement element)
{
Iterator iterator
=
element.getChildElements();
List list
=
new
ArrayList();
while
(iterator.hasNext())
{
OMNode omNode
=
(OMNode) iterator.next();
if
(omNode.getType()
==
OMNode.ELEMENT_NODE)
{
OMElement omElement
=
(OMElement) omNode;
if
( omElement.getLocalName().equals(
"
record
"
) )
{
FlightLegInfo flightLegInfo
=
getFlightLegInfo(omElement);
list.add(flightLegInfo);
}
}
}
return
null
;
}
private
static
FlightLegInfo getFlightLegInfo(OMElement element)
{
FlightLegInfo flightLegInfo
=
new
FlightLegInfo();
Iterator iterator
=
element.getChildElements();
while
(iterator.hasNext())
{
OMNode omNode
=
(OMNode) iterator.next();
if
(omNode.getType()
==
OMNode.ELEMENT_NODE)
{
OMElement omElement
=
(OMElement) omNode;
if
( omElement.getLocalName().equals(
"
flightNo
"
) )
{
flightLegInfo.setFlightNo(omElement.getText());
System.out.println(
"
flightNo:
"
+
omElement.getText());
}
if
( omElement.getLocalName().equals(
"
tailNo
"
) )
{
flightLegInfo.setTailNo(omElement.getText());
}
}
}
return
flightLegInfo;
}
}
需要自己转换成FlightLegInfo 的list, 图方便, 直接在转换函数里面打印了一些测试输出数据. 算是完成了service的开发.