蓝字为关键字,等号=后面为关键字值。

一、介绍

我们用的webservice是根据gsoap编译工具来实现,gSOAP的编译器能够自动的将用户定义的本地化的C或C++数据类型转变为符合XML语法的数据结构。同时gSOAP能够根据标准化的wsdl(完全符合wsdl书写格式)文件来生成本地需要的C或C++源代码以确定发送接收XML文件的格式;

二、使用说明

当前我们用到的gSOAP版本是2.8.3,下面是生成源码的wsdl文件;如果想要生成C代码,则在生成源码时指定-c选项;例如wsdl文件名称为host.wsdl,依据以下两步生成源码:

wsdl2h –c –s –o host.h host.wsdl(具体使用可以查看帮助,依据wsdl文件生成c头文件)

soapcpp2 –c host.h(依据c指定的头文件生成c源码)

一个简单host.wsdl文件:(/**/注释栏为wsdl说明)

------------------------------------------------华丽的分割线-------------------------------------

 <?xml version="1.0" encoding="UTF-8"?>/*指定版本及编码格式*/
/*definitions是wsdl根元素,下面通常包含以下元素,即types/ message/ portType/ operation/ binding/ service */
<definitions name="MessageInfo"
xmlns:tns="http://messageinfo.com"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://messageinfo.com">
/*types是数据类型定义的元素 其应用主要是schema定义格式类型*/
<types>
<schema targetNamespace="http://messageinfo.com"
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="StatisticsRequest">
<sequence>
<element name="request" type="string"/>
</sequence>
</complexType>
<complexType name="StatisticsResponse">
<sequence>
<element name="AllPaketsnum" type="unsignedLong"/>
<element name="WormTypenum" type="unsignedLong"/>
<element name="Reverse1" type="string"/>
</sequence>
</complexType>
</schema>
</types>
/* message描述通信消息的数据结构的抽象化类型定义 */
<message name="GetMessageRequest">
<part name="Operateget" type="tns:StatisticsRequest"/>
</message>
<message name="GetMessageResponse">
<part name="Operateput" type="tns:StatisticsResponse"/>
</message>
/* portType描述服务和服务的方法 */
<portType name="MessagePortType">
<operation name="GetMessageRepq">
<input message="tns:GetMessageRequest"/>
<output message="tns:GetMessageResponse"/>
</operation>
</portType>
/* 描述通信协议,注意rpc document literal encoded各种匹配组合使用*/
<binding name="MessageSoapBinding" type="tns:MessagePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetMessageRepq">
<soap:operation style="rpc" soapAction=""/>
<input>
<soap:body use="literal" namespace="http://messageinfo.com"/>
</input>
<output>
<soap:body use="literal" namespace="http://messageinfo.com"/>
</output>
</operation>
</binding>
/*service描述webservice访问点的集合*/
<service name="MessageService">
<documentation>Stat Message Service Topsec Ips provide</documentation>
<port name="MessageSerPort" binding="tns:MessageSoapBinding">
<soap:address location="http://localhost:80"/>
</port>
</service> </definitions>

三、元素介绍

关于xml格式问题,参考xml文档,wsdl具体应用分为下面几类:

下面将对每个元素进行详细说明:

 1. Definitions

定义了文档中用到的各个xml元素的namespace缩写,

也界定了本文档自己的 targetNamespace="http://www.jsoso.com/wstest",

这意味着其它的XML要引用当前XML中的元素时,要声明这个namespace。

注意xmlns:tns="http://www.jsoso.com/wstest"这个声明,它标示了使用tns这个前缀 指向自身的命名空间

 <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns:="http://www.jsoso.com/wstest"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamesapce="http://www.jsoso.com/wstest"
name="Example">
......
</definitions>

 2. types

<types>标签定义了当前的WSDL文档用到的数据类型。

要说明的是,为了最大程度的平台中立性,WSDL 使用 XML Schema 语法来定义数据类型。

这些数据类型用来定义web service方法的参数和返回值。对于通用的原生数据类型如:

integer , boolean , char , float等,

在W3C的标准文档http://www.w3.org/2001/XMLSchema中已经做了定义。

这里我们要引入的schema定义 schemaLocation="http://localhost:8080/hello?xsd=1"是我们自定义的对象类型。

(自定义对象类型地址不存在wsdl会怎样处理?)

 <types>
<xsd:schema>
<sxd:import namespace="http://www.jsoso.com/wstest"
schemaLocation="http://localhost:8080/hello?xsd=1">
</xsd:import>
</xsd:schema>
</types>

3. message就是用来soap消息的

<message>元素定义了web service函数的参数。

<message>元素中的每个<part>子元素都和某个参数相符。

输入参数在<message>元素中定义,与输出参数相隔离,

输出参数有自己的<message>元素。

兼作输入、输出的参数在输入输出的<message>元素中有它们相应的<part>元素。

输出 <message>元素以"Response"结尾,对Java而言方法得返回值就对应一个输出的<message>。

每个<part>元素都有名字和类 型属性,就像函数的参数有参数名和参数类型。

 <message name="sayHello">
<part name="person" type="tns:person"></part>
<part name="arg1" type="xsd:string"></part>
</message> <message name="sayHelloResponse">
<part name="personList" type="tns:personArray"></part>
</message>
<message name="HelloException">
<part name="fault" element="tns:HelloException"></part>
</message>

4. portType

指明服务的接口名称。

在<operation>元素中,name属性表示服务方法名,

parameterOrder属性表示方法的参数顺序,

使用空格符分割多个参数,如:“parameterOrder="person arg1”。

<operation>元素的子标签<input>表示输入参数说明,它引用<message>标签中的输入参数。

<output>表示输出参数说明,它引用<message>标签中的输出参数。

<fault>标签在Java方法中的特别用来表示异常(其它语言有对应的错误处理机制),

它引用<message>标签中的错误参数。

 <portType name="Example"> 

    <operation name="toSayHello" parameterOrder="userName">
<input message="tns:toSayHello"></input>
<output message="tns:toSayHelloResponse"></output>
</operation>
<operation name="sayHello" parameterOrder="person arg1">
<input message="tns:sayHello"></input>
<output message="tns:sayHelloResponse"></output>
<fault message="tns:HelloException" name="HelloException"></fault>
</operation>
</portType>

5. binding

指定消息传递的格式,<binding>标签是完整描述协议、序列化和编码的地方,

<types>,<message>和<portType>标签处理抽象的数据内容,而<binding>标签是处理数据传输的物理实现。

<binding>标签把前三部分的抽象定义具体化。

style="rpc":消息的展现形式;有两个值,rpc和content

use="literal":消息应该以什么样的形式来传递;有两个值,literal和encodes。但目前都是用literal。

<operation>子标签将portType中定义的operation同SOAP的请求绑定,

定义了操作名称soapAction,输出输入参数和异常的编码方式及命名空间。

 <binding name="ExamplePortBinding" type="tns:Example">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding>
<operation name="toSayHello">
<soap:operation soapAction="sayHello"></soap:operation>
<input>
<soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body>
</input>
<output>
<soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body>
</output>
</operation>
<operation name="sayHello">
<soap:operation soapAction="sayHello"></soap:operation>
<input>
<soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body>
</input>
<output>
<soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body>
</output>
<fault name="HelloException">
<soap:fault name="HelloException" use="literal"></soap:fault>
</fault>
</operation>
</binding>

WSDL 绑定样式由两个属性组合而成:style、use;style可以是RPC/Document,use可以是Encoded/Literal;下面解释下这4个名词的意思:

RPC 样式

RPC样式指定<soap:body> 元素包含一个将被调用的web方法的名称的元素(wrapper element(封装元素))。这个元素依次为该方法的每个参数还有返回值作了记录。

Document 样式

如果是document 样式,就没有像在RPC样式中的wrapper元素。转而代之的是消息片断直接出现在<soap:body>元素之下。没有任何SOAP格式化规则规定<soap:body>元素下能包含什么;它包含的是一个发送者和接收者都达成一致的XML文档。

Encoded 编码

如果use的值是”encoded”, 则每个消息片段将使用类型属性来引用抽象类型。通过应用由 encodingStyle 属性所指定的编码样式,可使用这些抽象类型生成具体的消息。最常用到的SOAP编码样式是在SOAP1.1中定义的一组序列化规则,它说明了对象、结构、数组和图形对象应该如何序列化。通常,在应用程序中使用SOAP编码着重于远程进程调用和以后适合使用RPC消息样式。

Literal 文字

如果use 的值是”Literal”, 则每个片段使用 element 属性(对于简单片段)或 type 属性(对于复合片段)来引用具体架构,例如,数据根据指定的架构来序列化,这架构通常使用W3C XML架构来表述。

根据不同的组合,形成了四种绑定模型;另外,还有一种用Document模拟RPC样式的包装组合也很常见;

1.RPC/Encoded

2.RPC/Literal

3.Document/Encoded

4.Document/Literal

5.Document/Literal Wrapped

对于以上5种组合方式,由于Document/Encoded不被现有平台所支持,在实际中应用很少,所以这里就暂时不讨论该种组合;对于剩下的4种组合,我们结合一个表格和实例来对比下各自的优劣情况;

Binding Type  Advantage/DisAdvantage

RPC/Encoded 优点:

  1.WSDL文件的定义遵循直观和众所周知的远程进程调用的沟通模式。

  2.操作名显示在消息中,因此接收者很容易就把消息分派给它的实现。

  3.如果你正在你的服务中使用数据图形或者多态,这是惟一能使用的样式。

缺点:

  1.SOAP消息包含的类型编码信息就如xsi:type="xsd:int",这些就是一种开销。

  2.通常验证SOAP消息是很困难的,因为在WSDL Shcema中没有描述。

  3.RPC样式引起了一种在服务提供者和客户之间的紧密耦合,任何对接口的更改都会导致服务和客户间联系的中断。

  4.不被WSI一致性标准所支持。RPC/

Literal 优点:

  1.WSDL定义仍然像RPC/Encoded样式一样简单直接。

  2.操作名仍然出现在SOAP消息中。

  3.把类型编码从消息中排除了,因此提升了吞吐性能。

缺点:

  1.服务和客户之间仍然有紧密耦合。

  2.仍然难以用SOAP消息来验证传输的数据。

  3.它也不被WSI一致性标准所支持。

Document/Litaral   优点:

  1.在SOAP消息中没有类型编码信息。

  2.你总能用任何XML验证器来验证消息,在soap体中任何东西都在schema中有定义。

  3.使用document样式,规则不是那么严格,还有对XML Schema进行增强和更改时不会破坏接口。

  4.如果使用某特殊序列进行多进程调用,Document 样式可以保持应用程序的状态。

  5.Document样式更加适合异步处理。

  6.许多document-messaging服务能够选择文档的DOM和SAX 两种处理方式的其中一种,结果就是能最小化在内存中的处理。

缺点:

  1.WSDL定义变得更加复杂。

  2.在SOAP消息中的操作名没有了,没有了名称,把消息分派给它的实现方法就变得困难或不可能了。

Document/Literal

Wrapped  优点:

  1.包含了所有Document/Literal样式的优点。

  2.操作名出现在SOAP消息中。

缺点:

  1.即使WSDL定义变得更加复杂,但仍然有不少缺点。

  2.如果你在web服务中重载了操作,你就不能使用该样式。

6. service

service是一套<port>元素。

在一一对应形式下,每个<port>元素都和一个location关联。

如果同一个<binding>有多个<port>元素与之关联,

可以使用额外的URL地址作为替换。

一个WSDL文档中可以有多个<service>元素,

而且多个<service>元素十分有用,其中之一就是可以根据目标URL来组织端口。

在一个 WSDL文档中,<service>的name属性用来区分不同的service。

在同一个service中,不同端口,使用端口的"name"属性区 分。

 <service name="Example">
<port name="ExamplePort" binding="tns:ExamplePortBinding">
<soap:address location="http://localhost:8080/hello"></soap:address>
</port>
</service>

四、说明

这里编写webservice.c文件可以将需要的代码程序生成so(动态库),方便随时调用(具体使用说明参考gsoap)

 # Makefile for make libwebservice.so

 DIRS =
SHARE = -shared -lc
USER_LIBS = -lssl -ldl -lcrypto
MODULES = libwebservice.so
MODULES_OBJS = soapC.o soapServer.o stdsoap2.o webservice.o CFLAGS = -Wall -DWITH_OPENSSL all: $(MODULES) $(MODULES): $(MODULES_OBJS)
cc $(USER_LIBS) $(CFLAGS) ${SHARE} -o ${MODULES} $^
strip ${MODULES} clean:
rm *.o *.a *.so -rf
for filename in $(DIRS); do \
( cd $$filename; $(MAKE) $@ ); \
done

了解了整个结构,对传输类型及方式可以很好的把控,也可以将整个结构体进行传输及使用。

Linux下gsoap实现webservice功能的更多相关文章

  1. Linux下p2p的聊天功能实现

    Linux下p2p的聊天功能实现细节 Do one thing at a time, and do well. 今天闲着没事,写一个P2P的点对点的聊天功能的小程序,我觉得对网络编程初学者的学习很有用 ...

  2. Onvif开发之Linux下gsoap的使用及移植

    一直以来都是在CSDN上面学习别人的东西,很多次想写点什么但是又无从写起.由于公司项目需要,最近一段时间在研究onvif,在网上找了很多资料,发现资料是非常多,但是很少有比较全的资料,或者资料太多无从 ...

  3. jmeter压测、操作数据库、分布式linux下运行、webservice接口测试、charles抓包

    一.jmeter压测 在线程组中设置好,然后添加http请求,t添加聚合报告查看压力测试结果,如图: 一般压测时间10-15分钟,如果是稳定性测试,一般n*12小时,这些并发用户一直在请求. tps: ...

  4. linux下文件比对功能

    很想对吧两个文本有什么不同,可linux下有没有那么方便的工具,怎么办?其实也很简单:diff命令,一行搞定. 新建a.txt文件

  5. Linux下启用IP转发功能(主要针对Ubuntu的使用)

    说明:以下的操作只要在Linux下都是通用的. Linux发行版默认情况下是不开启IP转发功能的.如果架设一个Linux路由或者VPN服务就需要开启该服务. 1.通过访问sysctl的内核ipv4.i ...

  6. windows、linux 下启用mysql日志功能

    在默认情况下,mysql安装是没有启用日志管理功能的,这为后续的维护带来很多不便的地方. 查看是否启用了日志mysql>show variables like 'log_bin'; 怎样知道当前 ...

  7. 在Linux下编译带调试功能的Bochs

    在Linux下使用Bochs参考: http://wangcong.org/articles/bochs.html http://kinglaw05.blog.163.com/blog/static/ ...

  8. linux下gsoap的初次使用 -- c风格加法实例

    摘自: http://blog.csdn.net/jinpw/article/details/3346844 https://www.cnblogs.com/dkblog/archive/2011/0 ...

  9. Linux下Apache配置HTTPS功能

    Apache配置HTTPS功能  转 https://www.cnblogs.com/liaojiafa/p/6028816.html 一.yum 安装openssl和openssl-devel,ht ...

随机推荐

  1. JqGrid使用经验

    一.更改分页组件的样式 分页组件中

  2. 关于tableView的简单实例

    关于tableCell选中颜色 //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionSty ...

  3. 基于mini2440的看门狗(裸机)

    在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生 ...

  4. Java程序猿的JavaScript学习笔记(8——jQuery选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  5. iOS面试题04-runtime

    runtime/KVO等面试题 1.KVO内部实现原则 回答:1>KVO是基于runtime机制实现的 2>当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个 ...

  6. 注册表:无法打开 XXX 由于某个错误无法打开该密钥。详细信息:拒绝访问

    错误原因:没有注册表用户权限. 正确添加用户权限的步骤如下:(跟着图片步骤) 右击该项,权限: 选中想要添加为当前所有者的用户后,点击应用.如果没用户显示,可以从“其他用户或组”中添加进来. 权限添加 ...

  7. Objective-c 内存管理

    与 C 有一点类似,oc  需要使用 alloc 方法申请内存.不同的是,c 直接调用 free 函数来释放内存,而 oc 并不直接调用 dealloc 来释放.整个  oc 都使用对象引用,而且每一 ...

  8. POJ 2689 Prime Distance(素数筛选)

    题目链接:http://poj.org/problem?id=2689 题意:给出一个区间[L, R],找出区间内相连的,距离最近和距离最远的两个素数对.其中(1<=L<R<=2,1 ...

  9. jquery的extend()函数

    extend()是在写插件的过程中常用的方法,该方法有一些重载原型. 1.该方法的原型是: extend(dest,src1,src2,src3...); 它的含义是将src1,src2,src3.. ...

  10. C++编程规范之23:头文件应该自给自足

    摘要: 各司其责:应该确保所编写的每个头文件都能够独自进行编译,为此需要包含其内容所依赖的所有头文件. 如果一个文件包含某个头文件时,还要包含另一个头文件才能工作,就会增加交流障碍,给头文件的用户增添 ...