zoukankan      html  css  js  c++  java
  • 消息(3)——soap,xml及soap序列化器

    在上篇随笔中对于客户实例传递的xml实现中,手动定义了xml的数据格式,如果现在对产品实例进行传递,那么还要手动对产品实例进行xml进行数据格式化。现在有一套为数据传递定义的协议,那就是soap。其实html也是一种数据存储格式,但html更注重的是表现数据。

     

    (一)Soap是什么?

    Simple Object Access Protocol 简单对象访问协议。是一种轻量的,简单的,基于xml的协议。

    W3c中对它是这样描述的:

    它是一种通信协议,用于应用程序之间的能信,它是一种用于发送消息的格式,被设计用来通过互联网进行通信,它基于xml,独立于平台,语言,它简单且可以扩展,它可以允许绕过防火墙。

    可以所它认为是一种协议,同时它也是一种消息发送的格式。

     

    (二)soap版本

    Soap现在有两个版本,1.11.2版本。1.1版本是20005月发布的文档中描述的,它其中包含了大量互操作性问题及歧义,导致解释时出现偏差。21.2提供了一个更严密、更可靠的规范集合,它基于对协议和xml序列化进行绑定的一个抽象模型。(可以找相关协议规范阅读)

     

    (三)soap组成

    现在看一个soap包(soap是一种协议,也是一种用于发送消息的格式,所以可以叫它soap包)。现在通过WS来看看这个soap包是什么样子。

     

    建立Web服务,发布的方法就一个方法:

    [WebMethod]

    public string HelloWorld()

    {

    return "Hello World";

    }

     

    在客户调用端:

    首先生成代理,直接从web服务地址查找服务生成代理,然后调用:

    using ws = FirstInstance;

    [TestFixture]

    public class SoapTest

    {

    [Test]

    public void TestSimpleSoap()

        {

    ws.SelfService client = new ws.SelfService();

    Console.WriteLine(client.HelloWorld());

    }

    }

     

    测试的打印是正确的,现在进行抓包分析,对Http下的数据包截取有很多现成的工具,也可以自己写。

    这是客户端请求时的包(http头省略):

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

      <s:Body>

        <HelloWorld xmlns="http://tempuri.org/"

         xmlns:a="http://schemas.datacontract.org/2004/07/

    UnicodeTest.FirstInstance"

        xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>

      </s:Body>

    </s:Envelope>

     

    这是服务端响应的包:

     

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <soap:Body>

        <HelloWorldResponse xmlns="http://tempuri.org/">

          <HelloWorldResult>Hello World</HelloWorldResult>

        </HelloWorldResponse>

      </soap:Body>

    </soap:Envelope>

     

    这就是soap包。Soap包由封套Envelope组成,也叫信封,信封由一个soap头和包体组成,其中包体是必须的。

     

    现在对客户类实例进行传输。

    [WebMethod]

    public Customer GetCustomer()

    {

    Customer customer = new Customer

    {

    Unid = 13,

    CustomerName = "Songjiang",

    CreateTime = DateTime.Now,

    Telephone = new Call {

    Mobile = "1111111",

    FirmCall = "2222",

    HomeCall = "3333" }

    };

    return customer;

    }

     

    客户端:

    public void TestCustomerSoap()

    {

        ws.Customer customer = new ws.Customer();

    ws.SelfService client = new ws.SelfService();

    customer = client.GetCustomer();

    Console.WriteLine(customer.CustomerName);

    }

     

    WS返回的soap包是:

     

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"

      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <soap:Body>

        <GetCustomerResponse xmlns="http://tempuri.org/">

          <GetCustomerResult>

            <Unid>13</Unid>

            <CustomerName>Songjiang</CustomerName>

            <CreateTime>2010-03-31T11:40:52.3125+08:00</CreateTime>

            <Telephone>

              <HomeCall>3333</HomeCall>

              <Mobile>1111111</Mobile>

              <FirmCall>2222</FirmCall>

            </Telephone>

          </GetCustomerResult>

        </GetCustomerResponse>

      </soap:Body>

    </soap:Envelope>

     

    从中可以看到:

    <GetCustomerResponse xmlns="http://tempuri.org/">

          <GetCustomerResult>

            <Unid>13</Unid>

            <CustomerName>Songjiang</CustomerName>

            <CreateTime>2010-03-31T11:40:52.3125+08:00</CreateTime>

            <Telephone>

              <HomeCall>3333</HomeCall>

              <Mobile>1111111</Mobile>

              <FirmCall>2222</FirmCall>

            </Telephone>

          </GetCustomerResult>

        </GetCustomerResponse>

     

    这部分与上篇中的对客户类实例的xml数据格式化是很相近的。只是在整个过程中,自己没有进行显示的xml格式化。

    而由ws进行显示的xml序列化。

    现在看看通过XmlSerializer序列化器进行对客户类的手动序列化

     

    public void TestSerialize()

    {

        Customer customer = new Customer

        {

    Unid = 13,

    CustomerName = "Songjiang",

    CreateTime = DateTime.Now,

    Telephone = new Call {

    Mobile = "1111111",

    FirmCall = "2222",

    HomeCall = "3333" }

        };

     

        FileStream fs = new FileStream("xmltest.xml", FileMode.Create);

        XmlSerializer formatter = new XmlSerializer(typeof(Customer));

     

        formatter.Serialize(fs, customer);

        fs.Close();

    }

     

    文档内容:

    <?xml version="1.0"?>

    <Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <Unid>13</Unid>

      <CustomerName>Songjiang</CustomerName>

      <CreateTime>2010-03-31T11:55:32.375+08:00</CreateTime>

      <Telephone>

        <HomeCall>3333</HomeCall>

        <Mobile>1111111</Mobile>

        <FirmCall>2222</FirmCall>

      </Telephone>

    </Customer>

     

    更多XmlSerializer的内容请见:

    http://www.cnblogs.com/jams742003/archive/2010/03/03/1677288.html

     

    这个文档的内容与上篇中的内容相近。然后再来看看soap序列化器 SoapFormatter

    public void TestSoapSerialize()

    {

        Customer customer = new Customer

        {

    Unid = 13,

    CustomerName = "Songjiang",

    CreateTime = DateTime.Now,

    Telephone = new Call {

    Mobile = "1111111",

    FirmCall = "2222",

    HomeCall = "3333" }

        };

     

        FileStream fs = new FileStream("xmlSoap.xml", FileMode.Create);

        SoapFormatter formatter = new SoapFormatter();

     

        formatter.Serialize(fs, customer);

        fs.Close();

    }

     

    内容为:

    <SOAP-ENV:Envelope>

    <SOAP-ENV:Body>

    <a1:Customer id="ref-1">

    <_x003C_Unid_x003E_k__BackingField>

    13

    </_x003C_Unid_x003E_k__BackingField>

    <_x003C_CustomerName_x003E_k__BackingField id="ref-3">

    Songjiang

    </_x003C_CustomerName_x003E_k__BackingField>

    <_x003C_CreateTime_x003E_k__BackingField>

    2010-03-31T12:01:08.8750000+08:00

    </_x003C_CreateTime_x003E_k__BackingField>

    <_x003C_Telephone_x003E_k__BackingField href="#ref-4"/>

    </a1:Customer>

    <a1:Call>

    <_x003C_HomeCall_x003E_k__BackingField id="ref-5">

    3333

    </_x003C_HomeCall_x003E_k__BackingField>

    <_x003C_Mobile_x003E_k__BackingField id="ref-6">

    1111111

    </_x003C_Mobile_x003E_k__BackingField>

    <_x003C_FirmCall_x003E_k__BackingField id="ref-7">

    2222

    </_x003C_FirmCall_x003E_k__BackingField>

    </a1:Call>

    </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

     

    是一个完整的封套(为了排版好看我删除了一些名字空间样的字串,其实这样也不好看)。

     

    博客园大道至简

    http://www.cnblogs.com/jams742003/

    转载请注明:博客园

  • 相关阅读:
    cds.data:=dsp.data赋值有时会出现AV错误剖析
    iOS -- 十进制、十六进制字符串,byte,data等之间的转换
    iOS -- 原生NSStream实现socket
    CA认证原理以及实现(下)
    CA认证原理以及实现(上)
    android -- 存储byte
    iOS -- 字符串(NSString *)转uint8_t的两种方法
    Android -- AsyncTask 使用和缺陷
    Swift oc 混编
    Android -- native关键字
  • 原文地址:https://www.cnblogs.com/jams742003/p/1701277.html
Copyright © 2011-2022 走看看