网上关于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里面也有很多, 但是至今还没看到返回自定义对象的. 我写的如下:
{
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 如下:
< 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如下
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的开发.