Axis2/C是一个用C语言实现的Web Service引擎。
Axis2/C基于Axis2架构 ,支持SOAP1.1 和SOAP1.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,并加入如下代码:
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、编译上述代码,在命令行运行如下编译命令:
7、链接生成的中间对象,并产生DLL,运行命令如下:
8、在 % AXIS2_HOME%\services下创建目录hello, 将步骤7产生的hello.dll拷贝到其中,并创建服务描述文件services.xml,并插入如下内容:
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服务器,执行如下命令:
三、访问服务
10、在VS中创建项目Axis2Test,并在 Axis2Test.cpp中插入这些代码:
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 }