现在你知道如何根据WSDL用Axis2来生成客户端了,这部分我们将再深入一些,向你展示如何建立服务,以及从无到有,白手起家建立服务和客户端。


package org.apache.axis2.axis2userguide;
import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
public class SampleService {
public OMElement sayHello(OMElement element)
throws XMLStreamException {
element.build();
element.detach();
String rootName = element.getLocalName();
System.out.println("Reading "+rootName+" element");
OMElement childElement = element.getFirstElement();
String personToGreet = childElement.getText();
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("sayHelloResponse", omNs);
OMElement value = fac.createOMElement("greeting", omNs);
value.addChild(fac.createOMText(value, "Hello, " + personToGreet));
method.addChild(value);
return method;
}
private void ping(){
}
}
在编译源码的时候确认Axis2库包含在你的classpath中。Axis2使用AXIOM,或者说AXIs对象模型,一个基于StAX API(Streaming API for XML)的类DOM (Document Object Model)结构。作为服务的方法必须接受一个OMElement对象作为它的参数,这个参数代表输入SOAP消息的负载内容。(OMElement是用AXIOM来表示XML元素的方式,就象一个DOM元素对象一样。)在这个例子里,你展开负载中第一个子元素的内容,加入文本,并将它作为返回OMElement的内容。除非这是一个“in only”服务。这些方法必须返回一个OMElement,因为它将会作为返回SOAP消息的负载内容。要将这个类转变为服务,建立服务描述文件services.xml,如代码列表9。
<service name="UserGuideSampleService">
<description>
This is a sample service created in the Axis2 User's Guide
</description>
<parameter name="ServiceClass">org.apache.axis2.axis2userguide.SampleService</parameter>
<operation name="sayHello">
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
<operation name="ping">
<messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
</operation>
</service>
这个文档定义了服务,这些服务会被Web管理应用调用,这些类将用来为请求服务。对于每一个操作,它定义了合适的消息接收类。在存放这些类的主目录中建立一个新目录META-INF(在这个例子中,主目录是包含org目录的那个),并将services.xml文件放在里面。输入命令:jar cvf SampleService.aar ./*来建立aar文件。用Web管理应用或者复制该文件到Axis2的services目录来部署 SampleService.aar文件。现在可以建立一个直接访问服务的客户端类(见代码列表10)。
package org.apache.axis2.axis2userguide;
import javax.xml.stream.XMLStreamException;
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.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.Constants;
import org.apache.axis2.client.ServiceClient;
public class SampleClient {
private static EndpointReference targetEPR =
new EndpointReference(
"http://localhost:8080/axis2/services/UserGuideSampleService");
public static OMElement greetUserPayload(String personToGreet) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://example1.org/example1", "example1");
OMElement method = fac.createOMElement("sayHello", omNs);
OMElement value = fac.createOMElement("personToGreet", omNs);
value.addChild(fac.createOMText(value, personToGreet));
method.addChild(value);
return method;
}
public static void main(String[] args) {
try {
OMElement payload = SampleClient.greetUserPayload("John");
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMElement result = sender.sendReceive(payload);
String response = result.getFirstElement().getText();
System.out.println(response);
} catch (Exception e) { //(XMLStreamException e) {
System.out.println(e.toString());
}
}
}
这个类使用了发送和接收OMElements的相同技术,但是要着重指出的是Options类的使用。这个类可以让你决定例如返回消息传输者之类的参数(用来输出消息的传输者可以在目的地址的URL中指定)以及使用的SOAP版本。除了提供影响客户端和服务交互的特定属性的set和get方法外,Options类还能让你在Options对象间建立继承关系。所以,如果在当前使用的Options对象中没有发现某个属性,客户端可以检查该对象的父类对象。编译执行上述SampleClient.java文件。确认所有的axis2库在classpath中。如果一切运行正常,‘Hello, John’将在控制台上输出。
package org.apache.axis2.axis2userguide;
public class SampleService {
public void doInOnly(){
return;
}
public String noParameters(){
return "Hello";
}
public String twoWayOneParameterEcho(String toEcho){
return toEcho;
}
public boolean multipleParametersAdd(float price, int itemId,
String description, String itemName){
//Code to handle the logic
return true;
}
}
接着,你需要告诉Axis2哪个类对应于哪个Web service调用。建立services.xml文件并加入代码列表12中的内容就可以做到这一点。
<service name="SampleService" scope="application">
<description>
Sample Service
</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">
org.apache.axis2.axis2userguide.SampleService
</parameter>
</service>
这个文件为服务设置了InOnly和InOut两种MEP,并告诉Axis2调用哪个类;操作和方法名必须匹配。换句话说,Axis2自动发送一个multipleParametersAdd调用到org.apache.axis2.axis2userguide.SampleService.multipleParametersAdd()方法。现在可以建立发行包了,将你的文件按照如下目录结构安排好(见代码列表13)。
- SampleService
- META-INF
- services.xml
- org
- apache
- axis2
- axis2userguide
- SampleService.class
最后,将SampleService 目录复制到servlet引擎的webapps/axis2/WEB-INF/services 目录,这样服务就部署好了。如果你要确认服务被正确部署,可以查看http://<host>:<port>/axis2/services/listServices。
/**
* Axis2UserGuideServiceSkeleton.java
*
* This file was auto-generated from WSDL
* by the Apache Axis2 version: SNAPSHOT Oct 15, 2006 (11:23:18
GMT+00:00)
*/
package org.apache.axis2.axis2userguide;
/**
* Axis2UserGuideServiceSkeleton java skeleton for the axisService
*/
public class Axis2UserGuideServiceSkeleton {
/**
* Auto generated method signature
* @param param7
*/
public org.apache.axis2.axis2userguide.NoParametersResponse
NoParameters
(org.apache.axis2.axis2userguide.NoParametersRequest param7)
{
System.out.println(param7);
NoParametersResponse res =
new NoParametersResponse();
return res;
}
/**
* Auto generated method signature
* @param param9
*/
public
org.apache.axis2.axis2userguide.TwoWayOneParameterEchoResponse
TwoWayOneParameterEcho
(
org.apache.axis2.axis2userguide.TwoWayOneParameterEchoRequest
param9
)
{
System.out.println(param9.getEchoString());
TwoWayOneParameterEchoResponse res =
new TwoWayOneParameterEchoResponse();
res.setEchoString(param9.getEchoString());
return res;
}
/**
* Auto generated method signature
* @param param11
*/
public void DoInOnly
(
org.apache.axis2.axis2userguide.DoInOnlyRequest param11
)
{
System.out.println(param11.getMessageString());
}
/**
* Auto generated method signature
* @param param12
*/
public
org.apache.axis2.axis2userguide.MultipleParametersAddItemResponse
MultipleParametersAddItem
(
org.apache.axis2.axis2userguide.MultipleParametersAddItemRequest
param12
)
{
System.out.println(param12.getPrice());
System.out.println(param12.getItemId());
System.out.println(param12.getDescription());
System.out.println(param12.getItemName());
MultipleParametersAddItemResponse res =
new MultipleParametersAddItemResponse();
res.setSuccessfulAdd(true);
res.setItemId(param12.getItemId());
return res;
}
}
同生成客户端一样,所有这些类,例如MultipleParametersAddItemRequest和TwoWayOneParameterEchoResponse是用工具生成的,可以作为框架文件在同一个目录下被找到。它们包括许多方法,例如setSuccessfulAdd(),它设置反馈元素的内容值,getItemName(),它获取请求中的元素内容。
