代码的添加主要是在axis2_skel_DmsServer.c中作处理,打开该文件就可以看到其中的TODO列表。上边会有注释:TODO fill this with the necessary business logic。在这其中依据程序逻辑添加处理过程。在eucaluptus的处理过程中,做了额外的自动化处理,可以更加方便地进行逻辑添加,同时也不用担心在wsdl有改动重新生成代码时的覆盖问题。下面将会介绍eucalyptus的具体修改流程,以及服务的具体书写规范。
1、修改axis2_skel_DmsServer.c文件
在axis2_skel_DmsServer.c文件中,是具体的服务端逻辑实现部分。在eucalyptus中,对这部分具体的逻辑处理函数进行了自动化的替换,具体的逻辑实现由一个cc-client-marshal-adb.c来实现。
通过参看下具体的代码查看修改更正过程。
通过自动化生成工具生成的服务类代码如下:
#include "axis2_skel_DmsServer.h" adb_ProductCompleteResponse_t* axis2_skel_DmsServer_ProductComplete (const axutil_env_t *env, adb_ProductComplete_t *productComplete ) { /* TODO fill this with the necessary business logic */ Return NULL; }
如果需要具体的逻辑实现,只需要在其中添加代码即可。如果在服务已经确定的情况下还行,如果要提供的服务不定,需要中途生成代码,那么直接在其中作修改,便会导致添加的代码被覆盖的悲剧。因而,在生产实践中,需要将具体的实现另摘取出来,放到额外的地方去实现她,eucalyptus实现的就是这种方式。
eucalyptus在编译的时候采用了自己一个小工具add_marshalling.pl,通过正则替换,引入了新的处理文件,将逻辑实现定位到外部去处理。采用add_marshalling.pl处理后的结果如下:
#include "axis2_skel_DmsServer.h" #include <server-marshal.h> adb_ProductCompleteResponse_t* axis2_skel_DmsServer_ProductComplete ( const axutil_env_t *env , adb_ProductComplete_t* productComplete ) return (ProductCompleteMarshal(productComplete, env));}
这样的话,具体服务逻辑的执行,就都可以将其移动server-marshal中实现了,按照其中正则匹配的规则在server-marshal中实现对应的逻辑处理函数。
2、进行事务处理
这里不会介绍所有详细的事务处理内容,只是介绍基本原则。比如解析request请求,进行逻辑处理,构造response请求并返回。
一般来说请求的request类型就是wsdl中message绑定中指定的element元素,然后由request获取到具体的自定义的类型。具体可以参看示例代码部分。
<wsdl:types> <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://server.ips.com"> <xs:complexType name="ProductCompleteType"> <xs:sequence> <xs:element minOccurs="0" name="productCategory" nillable="true" type="xs:string"/> <xs:element minOccurs="0" name="productName" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="ProductCompleteResponseType"> <xs:sequence> <xs:element minOccurs="0" name="result" type="xs:boolean"/> <xs:element minOccurs="0" name="message" nillable="true" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:element name="ProductComplete" type="tns:ProductCompleteType"/> <xs:element name="ProductCompleteResponse" type="tns:ProductCompleteResponseType"/> </xs:schema> </wsdl:types> <wsdl:message name="ProductCompleteRequestMsg"> <wsdl:part name="ProductCompleteRequestMsgReq" element="tns:ProductComplete"/> </wsdl:message> <wsdl:message name="ProductCompleteResponseMsg"> <wsdl:part name="ProductCompleteResponseMsgResq" element="tns:ProductCompleteResponse"/> </wsdl:message>
这一类请求消息是一层一层封装起来的,比如wsdl message中的消息ProductComplete对应的就是adb_ProductComplete_t类型,ProductComplete这个消息是由自定义的类型ProductCompleteType构成的。因而,从adb_ProductComplete_t中可以得到自定义的类型adb_ProductCompleteType_t,通过adb_ProductComplete_get_ProductComplete这个方法获取到。通过wsdl可以看到ProductCompleteType也有一些元素构成,那么对应的类型adb_ProductCompleteType_t就有一些方法可以获取到这些自定义类型,如adb_ProductCompleteType_get_productCategory和adb_ProductCompleteType_get_productName。
Response的构造与此类似,具体的方法查看,可以通过参考示例代码获取。同时也可以查看对应的类型头文件,从头文件中获取到对应的方法列表。
这里介绍的示例是比较简单的类型,复杂的比如有集合形式的处理,这个可以参看axis2c的文档了。
3、服务的编译
gcc -g -shared -olibDmsServer.so -fPIC -I $AXIS2C_HOME/include/axis2-1.6.0/ -I .. -Isrc -L$AXIS2C_HOME/lib \
-laxutil \
-laxis2_axiom \
-laxis2_engine \
-laxis2_parser \
-lpthread \
-laxis2_http_sender \
-laxis2_http_receiver \
-lguththila \
*.c ../*.c
4、服务的简单测试:
将生成的服务库libDmsServer.so和wsdl文件以及services.xml复制到${AXIS2C_HOME}/services/DmsServer,其中DmsServer的名字是服务的名字。
此处需要配置services.xml和httpconf,进行apache的部署。
可以直接采用axis2c自带的服务程序进行测试,启动axis2_http_server服务,默认在http://127.0.0.1:9090/axis2c/services就可以看到服务列表了,以及可以使用的接口。