Axis2/C 是以 C 語言實作的 Web Service 引擎,基於 Axis2 架構,支援 SOAP 1.1/1.2 與 REST 風格,同一服務可同時以 SOAP 與 REST 暴露。
axis2c-bin-1.6.0-win32.zip 並解壓AXIS2_HOME 指向解壓目錄Path 加入 %AXIS2_HOME%\lib 及 VC 執行庫路徑hello_svc.c
#include <axis2_svc_skeleton.h>
#include <axiom_text.h>
#include <axiom_node.h>
#include <axiom_element.h>
#include <stdio.h>
axiom_node_t* axis2_hello_greet(const axutil_env_t* env, axiom_node_t* node) {
axiom_node_t *child = NULL, *ret = NULL;
AXIS2_ENV_CHECK(env, NULL);
if (node) {
child = axiom_node_get_first_child(node, env);
if (child && axiom_node_get_node_type(child, env) == AXIOM_TEXT) {
axiom_text_t* text = (axiom_text_t*)axiom_node_get_data_element(child, env);
if (text && axiom_text_get_value(text, env)) {
const axis2_char_t* str = axiom_text_get_value(text, env);
printf("Client said: %s\n", str);
return build_greeting_response(env, "Hello Client!");
}
}
}
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST, AXIS2_FAILURE);
return build_greeting_response(env, "Client! Who are you?");
}
axiom_node_t* build_greeting_response(const axutil_env_t* env, axis2_char_t* greeting) {
axiom_node_t* n = NULL;
axiom_element_t* e = axiom_element_create(env, NULL, "greetResponse", NULL, &n);
axiom_element_set_text(e, env, greeting, n);
return n;
}
// 必須實作的 4 個生命週期函式
int AXIS2_CALL hello_init(axis2_svc_skeleton_t* svc, const axutil_env_t* env) {
svc->func_array = axutil_array_list_create(env, 0);
axutil_array_list_add(svc->func_array, env, "helloString");
return AXIS2_SUCCESS;
}
axiom_node_t* AXIS2_CALL hello_invoke(axis2_svc_skeleton_t* svc, const axutil_env_t* env, axiom_node_t* node, axis2_msg_ctx_t* ctx) {
return axis2_hello_greet(env, node);
}
axiom_node_t* AXIS2_CALL hello_on_fault(axis2_svc_skeleton_t* svc, const axutil_env_t* env, axiom_node_t* node) {
axiom_node_t *n = NULL;
axiom_element_t* e = axiom_element_create(env, node, "EchoServiceError", NULL, &n);
axiom_element_set_text(e, env, "Echo service failed", n);
return n;
}
int AXIS2_CALL hello_free(axis2_svc_skeleton_t* svc, const axutil_env_t* env) {
if (svc->func_array) axutil_array_list_free(svc->func_array, env);
AXIS2_FREE(env->allocator, svc);
return AXIS2_SUCCESS;
}
// 匯出介面
AXIS2_EXPORT int axis2_get_instance(axis2_svc_skeleton_t** inst, const axutil_env_t* env) {
*inst = (axis2_svc_skeleton_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_svc_skeleton_t));
(*inst)->ops = &hello_svc_skeleton_ops_var;
(*inst)->func_array = NULL;
return AXIS2_SUCCESS;
}
AXIS2_EXPORT int axis2_remove_instance(axis2_svc_skeleton_t* inst, const axutil_env_t* env) {
return AXIS2_SVC_SKELETON_FREE(inst, env);
}
cl /D "WIN32" /D "_WINDOWS" /D "AXIS2_DECLARE_EXPORT" /D "AXIS2_SVR_MULTI_THREADED" /I %AXIS2_HOME%\include /c hello_svc.c
link /DLL /OUT:hello.dll /LIBPATH:%AXIS2_HOME%\lib axutil.lib axiom.lib axis2_parser.lib axis2_engine.lib hello_svc.obj
%AXIS2_HOME%\services 建立 hello 目錄hello.dll 至該目錄services.xml:
<?xml version="1.0" encoding="utf-8"?>
<service name="hello">
<parameter name="ServiceClass" locked="xsd:false">hello</parameter>
<description>Quick start hello service</description>
<operation name="greet">
<parameter name="wsamapping">https://ws.apache.org/axis2/c/samples/hello</parameter>
</operation>
</service>
axis2_http_server
預設監聽 https://localhost:9090/axis2/services/
#include <axiom.h>
#include <axis2_client.h>
#include <axis2_util.h>
axiom_node_t* build_om_request(const axutil_env_t* env) {
axiom_node_t* n = NULL;
axiom_element_t* e = axiom_element_create(env, NULL, "greet", NULL, &n);
axiom_element_set_text(e, env, "Hello Server!", n);
return n;
}
const axis2_char_t* process_om_response(const axutil_env_t* env, axiom_node_t* node) {
if (node) {
axiom_node_t* child = axiom_node_get_first_child(node, env);
if (child && axiom_node_get_node_type(child, env) == AXIOM_TEXT) {
axiom_text_t* t = (axiom_text_t*)axiom_node_get_data_element(child, env);
if (t && axiom_text_get_value(t, env)) return axiom_text_get_value(t, env);
}
}
return NULL;
}
int main(int argc, char** argv) {
const axutil_env_t* env = axutil_env_create_all("hello_client.log", AXIS2_LOG_LEVEL_TRACE);
axis2_options_t* opts = axis2_options_create(env);
const axis2_char_t* addr = "https://localhost:9090/axis2/services/hello";
if (argc > 1) addr = argv[1];
axis2_endpoint_ref_t* ep = axis2_endpoint_ref_create(env, addr);
axis2_options_set_to(opts, env, ep);
axis2_options_set_action(opts, env, "https://ws.apache.org/axis2/c/samples/hello");
axis2_svc_client_t* client = axis2_svc_client_create(env, getenv("AXIS2C_HOME"));
axis2_svc_client_set_options(client, env, opts);
axiom_node_t* payload = build_om_request(env);
axiom_node_t* resp = axis2_svc_client_send_receive(client, env, payload);
if (resp) {
const axis2_char_t* greeting = process_om_response(env, resp);
printf("Response: %s\n", greeting);
axiom_node_free_tree(resp, env);
}
axis2_svc_client_free(client, env);
axutil_env_free((axutil_env_t*)env);
return 0;
}
執行客戶端,伺服器收到 Hello Server!,回應 Hello Client!,完成 SOAP 通訊閉環。