IT技术小屋

秋风秋雨,皆入我心

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  38 随笔 :: 1 文章 :: 19 评论 :: 0 Trackbacks
Axis2/C是一个用C语言实现的Web Service引擎。

Axis2/C基于Axis2架构,支持SOAP1.1SOAP1.2协议,并且支持RESTful风格的Web Service。基于Axis2/C的Web Service可以同时暴露为SOAP和RESTful风格的服务。

最近研究了一下Axis2/C,这篇文章详述了如何利用Axis2/C发布一个Web Service,并通过SOAP访问这个Web Service。

一、Axis2/C的下载和安装
1、可以从Axis2/C的官方网站下载到最新的Axis2/C发布包:Axis2/C下载

2、解压axis2c-bin-1.6.0-win32.zip,并在系统的环境变量中添加AXIS2_HOME并指向Axis2/C的解压目录,这样可以确保后续编译过程中可以找到Axis2/C的依赖项;

3、在系统环境变量中找到Path项,编辑该项,在它的最开始加入C:\VS8\Common7\IDE,并以分号分隔,以此保证编译后的客户端程序可以顺利找到依赖项;

4、在Path的结尾添加%AXIS2_HOME%\lib,确保编译器可以找到Axis2/C的依赖项;

二、构建和发布服务
5、新建CPP文件,命名为:hello_svc.c,并加入如下代码:
  1 #include "stdafx.h"
  2 
  3 #include <axis2_svc_skeleton.h>
  4 #include <axutil_log_default.h>
  5 #include <axutil_error_default.h>
  6 #include <axutil_array_list.h>
  7 #include <axiom_text.h>
  8 #include <axiom_node.h>
  9 #include <axiom_element.h>
 10 #include <stdio.h>
 11 
 12 axiom_node_t *axis2_hello_greet(const axutil_env_t *env, axiom_node_t *node);
 13 int AXIS2_CALL hello_free(axis2_svc_skeleton_t *svc_skeleton, const axutil_env_t *env);
 14 axiom_node_t* AXIS2_CALL hello_invoke(axis2_svc_skeleton_t *svc_skeleton, const axutil_env_t *env, axiom_node_t *node, axis2_msg_ctx_t *msg_ctx);
 15 int AXIS2_CALL hello_init(axis2_svc_skeleton_t *svc_skeleton, const axutil_env_t *env);
 16 axiom_node_t* AXIS2_CALL hello_on_fault(axis2_svc_skeleton_t *svc_skeli, const axutil_env_t *env, axiom_node_t *node);
 17 axiom_node_t *build_greeting_response(const axutil_env_t *env, axis2_char_t *greeting);
 18 
 19 axiom_node_t *axis2_hello_greet(const axutil_env_t *env, axiom_node_t *node)
 20 {
 21     axiom_node_t *client_greeting_node = NULL;
 22     axiom_node_t *return_node = NULL;
 23     AXIS2_ENV_CHECK(env, NULL);
 24     if (node)
 25     {
 26         client_greeting_node = axiom_node_get_first_child(node, env);
 27         if (client_greeting_node && axiom_node_get_node_type(client_greeting_node, env) == AXIOM_TEXT)
 28         {
 29             axiom_text_t *greeting = (axiom_text_t *)axiom_node_get_data_element(client_greeting_node, env);
 30             if (greeting && axiom_text_get_value(greeting , env))
 31             {
 32                 const axis2_char_t *greeting_str = axiom_text_get_value(greeting, env);
 33                 printf("Client greeted saying \"%s\" \n", greeting_str);
 34                 return_node = build_greeting_response(env, "Hello Client!");
 35             }
 36         }
 37     }
 38     else
 39     {
 40         AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);
 41         printf("ERROR: invalid XML in request\n");
 42         return_node = build_greeting_response(env, "Client! Who are you?");
 43     }
 44     return return_node;
 45 }
 46 
 47 
 48 
 49 axiom_node_t *build_greeting_response(const axutil_env_t *env, axis2_char_t *greeting)
 50 {
 51     axiom_node_t* greeting_om_node = NULL;
 52     axiom_element_t * greeting_om_ele = NULL;
 53     greeting_om_ele = axiom_element_create(env, NULL, "greetResponse", NULL, &greeting_om_node);
 54     axiom_element_set_text(greeting_om_ele, env, greeting, greeting_om_node);
 55     return greeting_om_node;
 56 }
 57 
 58 static const axis2_svc_skeleton_ops_t hello_svc_skeleton_ops_var = {
 59     hello_init,
 60     hello_invoke,
 61     hello_on_fault,
 62     hello_free
 63 };
 64 
 65 axis2_svc_skeleton_t *axis2_hello_create(const axutil_env_t *env)
 66 {
 67     axis2_svc_skeleton_t *svc_skeleton = NULL;
 68     svc_skeleton = (axis2_svc_skeleton_t *) AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_skeleton_t));
 69     svc_skeleton->ops = &hello_svc_skeleton_ops_var;
 70     svc_skeleton->func_array = NULL;
 71     return svc_skeleton;
 72 }
 73 
 74 int AXIS2_CALL hello_init(axis2_svc_skeleton_t *svc_skeleton, const axutil_env_t *env)
 75 {
 76     svc_skeleton->func_array = axutil_array_list_create(env, 0);
 77     axutil_array_list_add(svc_skeleton->func_array, env, "helloString");
 78     return AXIS2_SUCCESS;
 79 }
 80 
 81 
 82 
 83 axiom_node_t* AXIS2_CALL hello_invoke(axis2_svc_skeleton_t *svc_skeleton, const axutil_env_t *env, axiom_node_t *node, axis2_msg_ctx_t *msg_ctx)
 84 {
 85     return axis2_hello_greet(env, node);
 86 }
 87 
 88 axiom_node_t* AXIS2_CALL hello_on_fault(axis2_svc_skeleton_t *svc_skeli, const axutil_env_t *env, axiom_node_t *node)
 89 {
 90     axiom_node_t *error_node = NULL;
 91     axiom_node_t* text_node = NULL;
 92     axiom_element_t *error_ele = NULL;
 93     error_ele = axiom_element_create(env, node, "EchoServiceError", NULL,
 94         &error_node);
 95     axiom_element_set_text(error_ele, env, "Echo service failed ",
 96         text_node);
 97     return error_node;
 98 }
 99 
100 
101 
102 int AXIS2_CALL hello_free(axis2_svc_skeleton_t *svc_skeleton,
103            const axutil_env_t *env)
104 {
105     if (svc_skeleton->func_array)
106     {
107         axutil_array_list_free(svc_skeleton->func_array, env);
108         svc_skeleton->func_array = NULL;
109     }
110 
111     if (svc_skeleton)
112     {
113         AXIS2_FREE(env->allocator, svc_skeleton);
114         svc_skeleton = NULL;
115     }
116     return AXIS2_SUCCESS;
117 }
118 
119 AXIS2_EXPORT int axis2_get_instance(axis2_svc_skeleton_t **inst, const axutil_env_t *env)
120 {
121     *inst = axis2_hello_create(env);
122     if (!(*inst))
123     {
124         return AXIS2_FAILURE;
125     }
126     return AXIS2_SUCCESS;
127 }
128 
129 
130 
131 AXIS2_EXPORT int axis2_remove_instance(axis2_svc_skeleton_t *inst, const axutil_env_t *env)
132 {
133     axis2_status_t status = AXIS2_FAILURE;
134     if (inst)
135     {
136         status = AXIS2_SVC_SKELETON_FREE(inst, env);
137     }
138     return status;
139 }
140 

6、编译上述代码,在命令行运行如下编译命令:
$ C:\VS8\VC\bin\cl.exe /"WIN32" /"_WINDOWS" /"_MBCS" /"AXIS2_DECLARE_EXPORT" /"AXIS2_SVR_MULTI_THREADED" //nologo /
%AXIS2_HOME%\include /I C:\\VS8\\VC\\include /c hello_svc.c

7、链接生成的中间对象,并产生DLL,运行命令如下:
$ C:\VS8\VC\bin\link.exe /nologo /LIBPATH:
%AXIS2_HOME%\lib /LIBPATH:C:\\VS8\\VC\\lib axutil.lib axiom.lib axis2_parser.lib axis2_engine.lib /DLL /OUT:hello.dll *.obj

8、在
%AXIS2_HOME%\services下创建目录hello,将步骤7产生的hello.dll拷贝到其中,并创建服务描述文件services.xml,并插入如下内容:
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <service name="hello">
 3   <parameter name="ServiceClass" locked="xsd:false">hello</parameter>
 4   <description>
 5     Quick start guide hello service sample.
 6   </description>
 7   <operation name="greet">
 8     <parameter name="wsamapping">http://ws.apache.org/axis2/c/samples/hello</parameter>
 9   </operation>
10 </service>

9、启动Axis2服务器,执行如下命令:
$ axis2_http_server

三、访问服务
10、在VS中创建项目Axis2Test,并在
Axis2Test.cpp中插入这些代码:
  1 #include "stdafx.h"
  2 
  3 #include <stdio.h>
  4 #include <axiom.h>
  5 #include <axis2_util.h>
  6 #include <axiom_soap.h>
  7 #include <axis2_client.h>
  8 
  9 axiom_node_t *build_om_request(const axutil_env_t *env);
 10 const axis2_char_t *process_om_response(const axutil_env_t *env, axiom_node_t *node);
 11 
 12 int _tmain(int argc, char** argv)
 13 {
 14     const axutil_env_t *env = NULL;
 15     const axis2_char_t *address = NULL;
 16     axis2_endpoint_ref_t* endpoint_ref = NULL;
 17     axis2_options_t *options = NULL;
 18     const axis2_char_t *client_home = NULL;
 19     axis2_svc_client_t* svc_client = NULL;
 20     axiom_node_t *payload = NULL;
 21     axiom_node_t *ret_node = NULL;
 22 
 23     env = axutil_env_create_all("hello_client.log", AXIS2_LOG_LEVEL_TRACE);
 24     options = axis2_options_create(env);
 25     address = "http://localhost:9090/axis2/services/hello";
 26 
 27     if (argc > 1)
 28         address = argv[1];
 29 
 30     if (axutil_strcmp(address, "-h"== 0)
 31     {
 32         printf("Usage : %s [endpoint_url]\n", argv[0]);
 33         printf("use -h for help\n");
 34         return 0;
 35     }
 36 
 37     printf("Using endpoint : %s\n", address);
 38     endpoint_ref = axis2_endpoint_ref_create(env, address);
 39     axis2_options_set_to(options, env, endpoint_ref);
 40     axis2_options_set_action(options, env, "http://ws.apache.org/axis2/c/samples/hello");
 41 
 42     client_home = "E:\\mengli\\axis2c-bin-1.6.0-win32";//AXIS2_GETENV("AXIS2C_HOME");
 43     if (!client_home && !strcmp(client_home, ""))
 44         client_home = "../..";
 45 
 46     svc_client = axis2_svc_client_create(env, client_home);
 47     if (!svc_client)
 48     {
 49         printf("Error creating service client\n");
 50         AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"
 51             " %d :: %s", env->error->error_number,
 52             AXIS2_ERROR_GET_MESSAGE(env->error));
 53         return -1;
 54     }
 55 
 56     axis2_svc_client_set_options(svc_client, env, options);
 57     payload = build_om_request(env);
 58     ret_node = axis2_svc_client_send_receive(svc_client, env, payload);
 59 
 60     if (ret_node)
 61     {
 62         const axis2_char_t *greeting = process_om_response(env, ret_node);
 63         if (greeting)
 64             printf("\nReceived greeting: \"%s\" from service\n", greeting);
 65 
 66         axiom_node_free_tree(ret_node, env);
 67         ret_node = NULL;
 68     }
 69     else
 70     {
 71         AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Stub invoke FAILED: Error code:"
 72             " %d :: %s", env->error->error_number,
 73             AXIS2_ERROR_GET_MESSAGE(env->error));
 74         printf("hello client invoke FAILED!\n");
 75     }
 76 
 77     if (svc_client)
 78     {
 79         axis2_svc_client_free(svc_client, env);
 80         svc_client = NULL;
 81     }
 82 
 83     if (env)
 84     {
 85         axutil_env_free((axutil_env_t *) env);
 86         env = NULL;
 87     }
 88 
 89     return 0;
 90 
 91 }
 92 
 93 axiom_node_t *
 94 build_om_request(const axutil_env_t *env)
 95 {
 96     axiom_node_t* greet_om_node = NULL;
 97     axiom_element_t * greet_om_ele = NULL;
 98 
 99     greet_om_ele = axiom_element_create(env, NULL, "greet", NULL, &greet_om_node);
100     axiom_element_set_text(greet_om_ele, env, "Hello Server!", greet_om_node);
101 
102     return greet_om_node;
103 }
104 
105 
106 
107 const axis2_char_t *
108 process_om_response(const axutil_env_t *env,
109                     axiom_node_t *node)
110 {
111     axiom_node_t *service_greeting_node = NULL;
112     axiom_node_t *return_node = NULL;
113 
114     if (node)
115     {
116         service_greeting_node = axiom_node_get_first_child(node, env);
117 
118         if (service_greeting_node &&
119             axiom_node_get_node_type(service_greeting_node, env) == AXIOM_TEXT)
120         {
121             axiom_text_t *greeting = (axiom_text_t *)axiom_node_get_data_element(service_greeting_node, env);
122             if (greeting && axiom_text_get_value(greeting , env))
123             {
124                 return axiom_text_get_value(greeting, env);
125             }
126         }
127     }
128 
129     return NULL;
130 }

11、编译并执行该程序,会向远程服务发送字符串Hello Service!,并得到响应Hello Client!
转载请注明出处:原文链接
posted on 2011-07-05 16:33 Meng Lee 阅读(3823) 评论(1)  编辑  收藏

评论

# re: Axis2/C 基础入门 2011-07-05 17:38 wlu
顶顶顶  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: