我将开发一个将使用基于SOAP的Web服务的框架的应用程序。我做了一些研究,我有点像Axis2C框架,但在某些主题中,我发现原始的Axis2C实现遭受了内存泄漏,并且它已经停止了官方开发。
幸运的是,存在Axis2C非官方分支以及基于Axis2C的Staff框架。现在,问题是,哪个Axis2C后代更好或更容易使用?我知道,工作人员用C ++包装了Axis2C,但是我不介意普通C.工作人员是否也修复了内存泄漏?
感谢您的任何建议。
答案 0 :(得分:4)
我无法告诉你,Axis2 / C上的工作已经停止,它仍在继续,但速度非常慢。如果你查看trunk repo,你今年只能看到5次提交......中继版本1.7.0(未发布)有许多变化和新功能,但发布日期仍然未知。
原装Axis2 / C-1.6.0确实存在内存泄漏和已知问题,因此不适合生产。 Axis2 / C-unofficial基于原始Axis2 / C-1.6.0并修复了大多数关键问题并提供了其他有用的功能。 但是,非官方分支当然具有与原始API相同的API,您将花费相同的时间来开发服务或客户端。 使用它并不容易或更难。
如果我们谈论WSF员工,它的目的是快速开发WEB服务和客户端。与Axis2 / C相比,您只需编写几行代码即可启动服务或客户端工作。您不需要了解内部消息结构:您只使用简单(bool,int,string等)或复杂(struct,typedef,std容器......)类型(当然,您可以使用级别访问消息)。 Axis2 / C具有类似ADB(Axis数据绑定)的功能,但它是通过C-way完成的,您需要编写额外的代码行来访问请求和结果。
请注意ADB(和生成的服务)有内存泄漏,并且在非官方分支中没有修复。
比较一下使用起来更容易 - 亚行或工作人员我想举个例子:
注意:您需要手动在
{
和}
之间编写代码。
从Axis2 / C样本实现计算器服务的添加操作而不是ADB(传统)的Axis2 / C方式:
axiom_node_t *
axis2_calc_add(
const axutil_env_t * env,
axiom_node_t * node)
{
axiom_node_t *param1_node = NULL;
axiom_node_t *param1_text_node = NULL;
axis2_char_t *param1_str = NULL;
long int param1 = 0;
axiom_node_t *param2_node = NULL;
axiom_node_t *param2_text_node = NULL;
axis2_char_t *param2_str = NULL;
long int param2 = 0;
if (!node)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_SVC_SKEL_INPUT_OM_NODE_NULL,
AXIS2_FAILURE);
printf("Calculator client request ERROR: input parameter NULL\n");
return NULL;
}
/* iterating to the first child element skipping (empty) text elements */
for (param1_node = axiom_node_get_first_child(node, env);
param1_node && axiom_node_get_node_type(param1_node, env) != AXIOM_ELEMENT;
param1_node = axiom_node_get_next_sibling(param1_node, env));
if (!param1_node)
{
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST,
AXIS2_FAILURE);
printf("Calculator service ERROR: invalid XML in request\n");
return NULL;
}
param1_text_node = axiom_node_get_first_child(param1_node, env);
if (!param1_text_node)
{
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST,
AXIS2_FAILURE);
printf("Calculator service ERROR: invalid XML in request\n");
return NULL;
}
if (axiom_node_get_node_type(param1_text_node, env) == AXIOM_TEXT)
{
axiom_text_t *text =
(axiom_text_t *) axiom_node_get_data_element(param1_text_node, env);
if (text && axiom_text_get_value(text, env))
{
param1_str = (axis2_char_t *) axiom_text_get_value(text, env);
}
}
else
{
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST,
AXIS2_FAILURE);
printf("Calculator service ERROR: invalid XML in request\n");
return NULL;
}
/* iterating to the second child element skipping (empty) text elements */
for (param2_node = axiom_node_get_next_sibling(param1_node, env);
param2_node && axiom_node_get_node_type(param2_node, env) != AXIOM_ELEMENT;
param2_node = axiom_node_get_next_sibling(param2_node, env));
if (!param2_node)
{
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST,
AXIS2_FAILURE);
printf("Calculator service ERROR: invalid XML in request\n");
return NULL;
}
param2_text_node = axiom_node_get_first_child(param2_node, env);
if (!param2_text_node)
{
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST,
AXIS2_FAILURE);
printf("Calculator service ERROR: invalid XML in request\n");
return NULL;
}
if (axiom_node_get_node_type(param2_text_node, env) == AXIOM_TEXT)
{
axiom_text_t *text =
(axiom_text_t *) axiom_node_get_data_element(param2_text_node, env);
if (text && axiom_text_get_value(text, env))
{
param2_str = (axis2_char_t *) axiom_text_get_value(text, env);
}
}
else
{
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SVC_SKEL_INVALID_XML_FORMAT_IN_REQUEST,
AXIS2_FAILURE);
printf("Calculator service ERROR: invalid XML in request\n");
return NULL;
}
if (param1_str && param2_str)
{
long int result = 0;
axis2_char_t result_str[255];
axiom_element_t *ele1 = NULL;
axiom_node_t *node1 = NULL,
*node2 = NULL;
axiom_namespace_t *ns1 = NULL;
axiom_text_t *text1 = NULL;
param1 = strtol(param1_str, NULL, 10);
param2 = strtol(param2_str, NULL, 10);
result = param1 + param2;
sprintf(result_str, "%ld", result);
ns1 = axiom_namespace_create(env,
"http://axis2/test/namespace1", "ns1");
ele1 = axiom_element_create(env, NULL, "result", ns1, &node1);
text1 = axiom_text_create(env, node1, result_str, &node2);
return node1;
}
AXIS2_ERROR_SET(env->error,
AXIS2_ERROR_SVC_SKEL_INVALID_OPERATION_PARAMETERS_IN_SOAP_REQUEST,
AXIS2_FAILURE);
printf("Calculator service ERROR: invalid parameters\n");
return NULL;
}
从Axis2 / C codegen示例实现计算机服务WITH ADB的添加操作的Axis2 / C方式:
adb_addResponse_t * axis2_skel_Calculator_add(const axutil_env_t * env,
adb_add_t * add)
{
adb_addResponse_t * add_res = NULL;
int ret_val = 0;
int val1 = 0;
int val2 = 0;
val1 = adb_add_get_arg_0_0(add, env);
val2 = adb_add_get_arg_1_0(add, env);
ret_val = val1 + val2;
add_res = adb_addResponse_create(env);
adb_addResponse_set_addReturn(add_res, env, ret_val);
return add_res;
}
员工实施计算器服务添加操作的方式:
int CalculatorImpl::add(int param_1, int param_2)
{
return param_1 + param_2;
}
关于代码生成和编译过程,它将是:
对于Axis2 / C:
# generate service from WSDL
WSDL2C.sh -uri Calculator.wsdl -u -ss -sd
# implement src/axis2_skel_Calculator.c
# compile and install
cd src
# build
sh build.sh
# install
sudo mkdir $AXIS2C_HOME/services/calculator
sudo cp lib*.so ../resources/*.xml $AXIS2C_HOME/services/calculator
对于WSF员工:
# generate service from WSDL
staff_codegen -pwsdl -tcomponent_all Calculator.wsdl
# implement src/CalculatorImpl.cpp
# build and install
make && sudo -E make install
当然,你可以在Axis2 / C-unofficial上使用WSF Staff来获得两者的所有好处。
答案 1 :(得分:0)
事实证明,今天我在谷歌搜索时发现了Axis2c-unofficial,我需要查看它。
对于Axis2c(WSO2版本),我目前正在我的移动应用程序中使用它(基于Qt - Meego / BB10),您可能不想自己编写代码但是从WSDL文件生成代码。就像loentar所说的那样,WSO2版本实际上只是Axis2c的一个包装,但确实让它更容易设置。我会说使用WSO2版本或使用非官方版本,我发现Axis2c很难编译(我是C / C ++ / Qt / SOAP的新手,我试图为Meego / BB10交叉编译它 - 你可以想象怎么回事!),还记得STAFF是基于Qt的包装器,因此是另一个依赖。
底线是使用代码生成器,但要小心:
1 - 代码生成器有一个“其余的xml节点”(不记得方法/名称的名称)但基本上它无法映射的所有xml进入此节点,你可以对此运行xpath查询。但是,有时这个节点会被放在实际的真实节点对象之前,所以xml只会被转储到这个节点而不是你真正想要的节点对象。
2 - 生成的代码很大 - 我的意思是真的很大!我的移动图书馆大约190mb,大约40mb没有调试。
3 - 代码gen是java所以你可以使用eclipse让代码生成你的代码getter!
第三点非常重要,我个人认为这意味着我需要编写更少的代码,因为XML中的每个项都映射到一个字符串,而我的QML代码(GUI代码)只是解决了这个字符串。
我可能已经切入了一个选择 - 虽然我宁愿使用Java来生成代码(更好的支持),但希望这会有所帮助。
对JeFf的回应:
在我试图为BB10编写WSO2的困境中,我意识到WSO2只包含Axis2c文件夹,它首先编译各种asix2c库(我认为它首先编译),然后是WSO2库(sandesh,savan等) 。),我很幸运,我真正想要的只是WSDL的XML序列化/ deserialsation而不是任何高级的soap功能(除了基础知识之外我当然不太了解肥皂)。
假设头文件/ api完全相同,可以简单地用非正式的库替换axis2c库。或者甚至简单地将非官方文件夹放在官方文件夹上。
我自己必须首先在eclipse中编译二进制文件(BB10 SDK),这是一项漫长而艰巨的任务,但与Nokias Meego SDK不同,BB10没有交叉编译工具,在Meego中它非常简单我不得不做零变化。