首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Axis2/C 入門實戰:從安裝到發布與呼叫 SOAP Web Service

     編輯:關於C語言

Axis2/C 簡介

Axis2/C 是以 C 語言實作的 Web Service 引擎,基於 Axis2 架構,支援 SOAP 1.1/1.2 與 REST 風格,同一服務可同時以 SOAP 與 REST 暴露。

環境建置

  1. 下載 axis2c-bin-1.6.0-win32.zip 並解壓
  2. 設定環境變數 AXIS2_HOME 指向解壓目錄
  3. Path 加入 %AXIS2_HOME%\lib 及 VC 執行庫路徑

服務端開發

1. 實作服務骨架 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);
}

2. 編譯產生 DLL


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

3. 部署服務

  • 在 %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>

4. 啟動伺服器

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 通訊閉環。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved