zoukankan      html  css  js  c++  java
  • Linux下gsoap实现webservice功能

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

    一、介绍

    我们用的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说明)

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

     1 <?xml version="1.0" encoding="UTF-8"?>/*指定版本及编码格式*/
     2 /*definitions是wsdl根元素,下面通常包含以下元素,即types/ message/ portType/ operation/ binding/ service */
     3 <definitions name="MessageInfo"
     4     xmlns:tns="http://messageinfo.com"
     5     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     6     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
     7     xmlns="http://schemas.xmlsoap.org/wsdl/"
     8     targetNamespace="http://messageinfo.com">
     9 /*types是数据类型定义的元素 其应用主要是schema定义格式类型*/
    10 <types>
    11  <schema targetNamespace="http://messageinfo.com"
    12          xmlns="http://www.w3.org/2001/XMLSchema">
    13    <complexType name="StatisticsRequest">
    14     <sequence>
    15      <element name="request" type="string"/>
    16     </sequence>
    17    </complexType>
    18    <complexType name="StatisticsResponse">
    19     <sequence>
    20      <element name="AllPaketsnum" type="unsignedLong"/>
    21      <element name="WormTypenum" type="unsignedLong"/>
    22      <element name="Reverse1" type="string"/>
    23     </sequence>
    24    </complexType>
    25   </schema>
    26 </types>
    27 /* message描述通信消息的数据结构的抽象化类型定义 */
    28 <message name="GetMessageRequest">
    29  <part name="Operateget" type="tns:StatisticsRequest"/>
    30 </message>
    31 <message name="GetMessageResponse">
    32  <part name="Operateput" type="tns:StatisticsResponse"/>
    33 </message>
    34 /* portType描述服务和服务的方法 */
    35 <portType name="MessagePortType">
    36  <operation name="GetMessageRepq">
    37   <input message="tns:GetMessageRequest"/>
    38   <output message="tns:GetMessageResponse"/>
    39  </operation>
    40 </portType>
    41 /* 描述通信协议,注意rpc document literal encoded各种匹配组合使用*/
    42 <binding name="MessageSoapBinding" type="tns:MessagePortType">
    43  <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    44  <operation name="GetMessageRepq">
    45   <soap:operation style="rpc" soapAction=""/>
    46    <input>
    47     <soap:body use="literal" namespace="http://messageinfo.com"/>
    48    </input>
    49    <output>
    50     <soap:body use="literal" namespace="http://messageinfo.com"/>
    51    </output>
    52   </operation>
    53 </binding>
    54 /*service描述webservice访问点的集合*/
    55 <service name="MessageService">
    56  <documentation>Stat Message Service Topsec Ips provide</documentation>
    57  <port name="MessageSerPort" binding="tns:MessageSoapBinding">
    58    <soap:address location="http://localhost:80"/>
    59  </port>
    60 </service>
    61 
    62 </definitions>
    View Code

    三、元素介绍

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

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

     1. Definitions

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

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

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

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

    1 <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    2        xmlns:tns:="http://www.jsoso.com/wstest"
    3        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    4        xmlns="http://schemas.xmlsoap.org/wsdl/"
    5        targetNamesapce="http://www.jsoso.com/wstest"
    6        name="Example">
    7        ......
    8 </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会怎样处理?)

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

    3. message就是用来soap消息的

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

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

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

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

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

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

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

     1 <message name="sayHello"> 
     2    <part name="person" type="tns:person"></part> 
     3    <part name="arg1" type="xsd:string"></part> 
     4 </message> 
     5 
     6 <message name="sayHelloResponse"> 
     7    <part name="personList" type="tns:personArray"></part> 
     8 </message> 
     9 <message name="HelloException"> 
    10    <part name="fault" element="tns:HelloException"></part> 
    11 </message>

    4. portType

    指明服务的接口名称。

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

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

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

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

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

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

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

     1 <portType name="Example"> 
     2 
     3    <operation name="toSayHello" parameterOrder="userName"> 
     4      <input message="tns:toSayHello"></input> 
     5      <output message="tns:toSayHelloResponse"></output> 
     6    </operation> 
     7    <operation name="sayHello" parameterOrder="person arg1"> 
     8      <input message="tns:sayHello"></input> 
     9      <output message="tns:sayHelloResponse"></output> 
    10      <fault message="tns:HelloException" name="HelloException"></fault> 
    11    </operation> 
    12 </portType>

    5. binding

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

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

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

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

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

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

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

     1 <binding name="ExamplePortBinding" type="tns:Example"> 
     2    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding> 
     3    <operation name="toSayHello"> 
     4       <soap:operation soapAction="sayHello"></soap:operation> 
     5       <input> 
     6          <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 
     7       </input> 
     8       <output> 
     9         <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 
    10       </output> 
    11    </operation> 
    12    <operation name="sayHello"> 
    13       <soap:operation soapAction="sayHello"></soap:operation> 
    14       <input> 
    15          <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 
    16       </input> 
    17       <output> 
    18          <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 
    19       </output> 
    20       <fault name="HelloException"> 
    21           <soap:fault name="HelloException" use="literal"></soap:fault> 
    22       </fault> 
    23    </operation> 
    24 </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"属性区 分。

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

    四、说明

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

     1 # Makefile for make libwebservice.so
     2 
     3 DIRS =
     4 SHARE = -shared -lc
     5 USER_LIBS = -lssl -ldl -lcrypto
     6 MODULES = libwebservice.so
     7 MODULES_OBJS = soapC.o soapServer.o stdsoap2.o webservice.o
     8 
     9 CFLAGS = -Wall -DWITH_OPENSSL
    10 
    11 all: $(MODULES)
    12 
    13 $(MODULES): $(MODULES_OBJS)
    14         cc $(USER_LIBS) $(CFLAGS) ${SHARE} -o ${MODULES} $^
    15         strip ${MODULES}
    16 
    17 clean:
    18         rm *.o *.a *.so -rf
    19         for filename in $(DIRS); do 
    20                 ( cd $$filename;  $(MAKE) $@ ); 
    21         done

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

  • 相关阅读:
    CAD图形引擎库VectorDraw
    基于COM的矢量图像控件VectorDraw
    [转]电子表格Spread 7.0线上发布会
    ProEssentials图表教程汇总
    几种JS 引擎介绍(不同浏览器有不同的引擎)
    我的 学习链接
    ExtJS 2.3版 源代码的解析(转)
    javascript调试原理(一)(转)
    使用GoogleCode SVN服务
    javascript调试原理(二) 模拟实现 (转)
  • 原文地址:https://www.cnblogs.com/sdgwc/p/5099536.html
Copyright © 2011-2022 走看看