SyncOrderRelation是DSMP规范中SP必须实现的服务接口之一。DSMP规范的接口使用WebService作为通信方式,并且规范规定了必须使用SOAP1.2的document的绑定样式和literal的编码方式。
Axis是apache的SOAP(Simple Object Access Protocol)实现。是目前使用比较广泛的WebService实现,也是少数几个对document/literal支持的较好的实现.
在这里我将演示使用apache的axis工具包来实现SyncOrderRelation接口的demo。SyncOrderRelation的具体定义已经存在于DSMP中,因而不能采用现实现代码,然后从代码中导出定义的方式进行开发.而是采用通过WSDL生成代码的方式进行开发.
1. SyncOrderRelation的WSDL定义
SyncOrderRelation是DSMP的一部分,我现在只是将它从DSMP中提取出来形成一个单独的文件:SyncOrderRelation.wsdl,具体的内容如下:
<definitions
xmlns:ws="http://www.monternet.com/dsmp/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.ort/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:dsmp="http://www.monternet.com/dsmp/schemas/" targetNamespace="http://www.monternet.com/dsmp/wsdl/">
<types>
<schema
targetNamespace=http://www.monternet.com/dsmp/schemas/ xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified" attributeFormDefault="unqualified">
<complexType name="address_info_schema">
<sequence>
<element name="DeviceType" type="xsd:integer"/>
<element name="DeviceID" type="xsd:string"/>
</sequence>
</complexType>
<complexType name="user_id_schema">
<sequence>
<element name="UserIDType" type="xsd:integer"/>
<element name="MSISDN" type="xsd:string"/>
<element name="PseudoCode" type="xsd:base64Binary"/>
</sequence>
</complexType>
<!-- request & response -->
<element name="TransactionID" type="xsd:string"/>
<element name="SyncOrderRelationReq" type="dsmp:SyncOrderRelationReqType"/>
<complexType name="SyncOrderRelationReqType">
<sequence>
<element name="MsgType" type="xsd:string"/>
<element name="Version" type="xsd:string"/>
<element name="Send_Address" type="dsmp:address_info_schema"/>
<element name="Dest_Address" type="dsmp:address_info_schema"/>
<element name="FeeUser_ID" type="dsmp:user_id_schema"/>
<element name="DestUser_ID" type="dsmp:user_id_schema"/>
<element name="LinkID" type="xsd:string" minOccurs="0"/>
<element name="ActionID" type="xsd:integer"/>
<element name="ActionReasonID" type="xsd:integer"/>
<element name="SPID" type="xsd:string" minOccurs="0"/>
<element name="SPServiceID" type="xsd:string"/>
<element name="AccessMode" type="xsd:integer" minOccurs="0"/>
<element name="FeatureStr" type="xsd:base64Binary" minOccurs="0"/>
</sequence>
</complexType>
<element name="SyncOrderRelationResp" type="dsmp:SyncOrderRelationRespType"/>
<complexType name="SyncOrderRelationRespType">
<sequence>
<element name="MsgType" type="xsd:string"/>
<element name="Version" type="xsd:string"/>
<element name="hRet" type="xsd:integer"/>
</sequence>
</complexType>
</schema>
</types>
<message name="dsmp.transID">
<part name="TransactionID" element="dsmp:TransactionID"/>
</message>
<message name="ma.SyncOrderRelationReq">
<part name="SyncOrderRelationInput" element="dsmp:SyncOrderRelationReq"/>
</message>
<message name="ma.SyncOrderRelationResp">
<part name="SyncOrderRelationOutput" element="dsmp:SyncOrderRelationResp"/>
</message>
<portType name="maPort">
<operation name="SyncOrderRelation">
<input message="ws:ma.SyncOrderRelationReq"/>
<output message="ws:ma.SyncOrderRelationResp"/>
</operation>
</portType>
<binding name="maPortBinding" type="ws:maPort">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="SyncOrderRelation">
<soap:operation soapAction="sim.SyncOrderRelation"/>
<input>
<soap:body use="literal"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.monternet.com/dsmp/schemas/"/>
<soap:header message="ws:dsmp.transID" part="TransactionID" use="literal"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding" namespace="http://www.monternet.com/dsmp/schemas/"/>
</input>
<output>
<soap:body use="literal"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.monternet.com/dsmp/schemas/"/>
<soap:header message="ws:dsmp.transID" part="TransactionID" use="literal"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding"
namespace=" http://www.monternet.com/dsmp/schemas/"/>
</output>
</operation>
</binding>
<service name="dsmp">
<port name="maPort" binding="ws:maPortBinding">
<soap:address location="http://10.1.3.107:9001/axis/services/maPort"/>
</port>
</service>
</definitions>
在service的定义是同具体的实现环境相关,在你的环境中只需将location替换为你的环境的URI即可.
2. 开发运行环境的准备
我开发环境是:
OS:redhat 9.0(Kernel 2.4.20)
WebServer: tomcat 4.1.30
Java: j2sdk1.5.0
Axis1.1
我将tomcat和axis都安装在用户的HOME目录环境变量是:
TOMCAT_HOME=$HOME/ jakarta-tomcat-4.1.30
AXIS_HOME=$HOME/axis-1_1
在安装好tomcat和axis后,就需要将axis同tomcat集成到一起.这个步骤很简单,将$AXIS_HOME/webapps下的axis拷贝到$TOMCAT_HOME/webapps就完成了,然后在启动tomcat验证一下,在我的环境在IE中打开http://10.1.3.107:9001/axis 接后,点击Validate链接就可以看到验证结果了.
在验证成功后,还得为开发准备一下CLASSPATH了,我将axis相关的CLASSPATH放在一个独立的环境变量中.
AXISCLASSPATH= $AXIS_HOME/lib/axis.jar: $AXIS_HOME/lib /commons-discovery.jar: $AXIS_HOME/lib /commons-logging.jar: $AXIS_HOME/lib /jaxrpc.jar:$AXIS_LIB/saaj.jar: $AXIS_HOME/lib /log4j-1.2.8.jar: $AXIS_HOME/lib /xml-apis.jar: $AXIS_HOME/lib /xercesImpl.jar: $AXIS_HOME/lib /wsdl4j.jar; export AXISCLASSPATH
3. 产生代码
环境终于整理好了,现在可以开始编码了.其实是不用太多的编码的.
a. 首先使用WSDL2java从SyncOrderRelation生成代码
调用
java -cp $AXISCLASSPATH org.apache.axis.wsdl.WSDL2Java –s SyncOrderRelation
WSDL2java就为我们生成了基本的代码,在开发目录下多出了一个com目录,这就是代码存在的目录.我们只需要在./com/monternet/www/dsmp/wsdl/MaPortBindingImpl.java添加
我们的业务处理代码就行了.
b. 添加TransactionID的支持
让我们先看看MaPortBindingImp1.java:
/**
* MaPortBindingImpl.java
*
* This file was auto-generated from WSDL
* by the Apache Axis WSDL2Java emitter.
*/
package com.monternet.www.dsmp.wsdl;
public class MaPortBindingImpl implements com.monternet.www.dsmp.wsdl.MaPort
{
public com.monternet.www.dsmp.schemas.SyncOrderRelationRespType
syncOrderRelation(com.monternet.www.dsmp.schemas.SyncOrderRelationReqType
syncOrderRelationInput)
throws java.rmi.RemoteException
{
return null;
}
}
syncOrderRelation函数就是我们将要添加功能功能实现的地方.但是在添加功能之前,我还得加上DSMP要求的TransactionID SOAP Header的支持,axis为我们生成的代码中并没有为我们做这件事。因此我们得加上取得和设置TransactionID的代吗。添加后的代码如下
package com.monternet.www.dsmp.wsdl;
import org.apache.axis.message.*;
import org.apache.axis.*;
public class MaPortBindingImpl implements com.monternet.www.dsmp.wsdl.MaPort
{
public com.monternet.www.dsmp.schemas.SyncOrderRelationRespType
syncOrderRelation(com.monternet.www.dsmp.schemas.SyncOrderRelationReqType
syncOrderRelationInput)
throws java.rmi.RemoteException
{
String transactionID = getTransactionID();
//业务相关的代码
setTransactionID(transactionID);
return null;
}
public String getTransactionID() throws AxisFault
{
MessageContext ctx = org.apache.axis.MessageContext.getCurrentContext();
SOAPEnvelope env = ctx.getRequestMessage().getSOAPEnvelope();
SOAPHeaderElement soapHeaderElement =
env.getHeaderByName("http://www.monternet.com/dsmp/schemas/",
"TransactionID");
return (String)soapHeaderElement.getObjectValue();
}
public void setTransactionID(String transID) throws AxisFault
{
MessageContext ctx = org.apache.axis.MessageContext.getCurrentContext();
SOAPEnvelope env = ctx.getResponseMessage().getSOAPEnvelope();
SOAPHeaderElement headerElement =
new SOAPHeaderElement("http://www.monternet.com/dsmp/schemas/",
"TransactionID", transID);
env.addHeader(headerElement);
}
}
在上面我添加了两个函数,getTransactionID通过MessageContext取得RequestMessage从中取得TransactionID,setTransactionID向ResponseMessage中添加TransactionID.
c. 写业务代码
由于这只是一个demo,没有具体的业务实现,只是返回9001(系统忙)的回应,代码如下:
public com.monternet.www.dsmp.schemas.SyncOrderRelationRespType
syncOrderRelation(com.monternet.www.dsmp.schemas.SyncOrderRelationReqType
syncOrderRelationInput)
throws java.rmi.RemoteException
{
String transactionID = getTransactionID();
response.setVersion(syncOrderRelationInput.getVersion());
response.setMsgType(new String(“SyncOrderRelationResp”));
response.setHRet(new BigInteger("9001"));
setTransactionID(transactionID);
return response;
}
4. 编译和发布
先在开发目录下建立一个build目录,如下
mkdir build
软后对java代码进行编译:
javac -cp $AXISCLASSPATH:./build -d build ./com/monternet/www/dsmp/schemas/*.java
javac -cp $AXISCLASSPATH:./build -d build ./com/monternet/www/dsmp/wsdl/*.java
编译成功后就开始发布了.
发布分为两步:
- 将代码将代码从build/下拷贝到$TOMCAT_HOME/webapps/axis/WEB-INF/classes下
- 然后调用axis的发布命令
java -cp $AXISCLASSPATH org.apache.axis.client.AdminClient –h 10.1.3.107 -p 9001 ./com/monternet/www/dsmp/wsdl/deploy.wsdd
如果一切顺利,就可以正确处理DSMP发来的定购关系同步包了.
5. 这个只是一个JAVA版本的简单实现方法,如果使用的C/C++可以采用axis的C++版本,同样可以简单的实现WebService的功能.