zoukankan      html  css  js  c++  java
  • 消息(4)——WS附件传输,包体中的base64编码附件

    Soap包中可以存放数据的地方可以是soap头也可以是soap body部分。其中body部分是必须的,是重要的数据存放位置。Soap头中也可以放一些数据,例如Web服务中的安全中用户检测。例如:

    如果添加soap头,那么先要有一个从SoapHeader派生的类:

    public class SelfHeader : SoapHeader

    {

        public string UserName { get; set; }

    }

     

    然后web服务中先定义一个公共成员:

    public SelfHeader _soapHeader;

     

    然后在需要添加soap头的方法上添加soap头标签:

    [WebMethod]

    [SoapHeader("_soapHeader")]

    public string HelloWorld()

    {

    if (_soapHeader.UserName != "zhao")

    return "用户禁止访问!";

    return "Hello World";

    }

     

    在客户端进行访问服务时,须设置header属性:

    public void TestSimpleSoap()

    {

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

        ws.SelfHeader _header = new ws.SelfHeader();

        _header.UserName = "zzz";

     

        client.SelfHeaderValue = _header;

        Console.WriteLine(client.HelloWorld());

    }

     

    现在看一下现在的soap包的情况:

    请求:

    <?xml version="1.0" encoding="utf-8"?>

    <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:Header>

        <SelfHeader xmlns="http://192.168.1.105/">

          <UserName>zzz</UserName>

        </SelfHeader>

      </soap:Header>

      <soap:Body>

        <HelloWorld xmlns="http://192.168.1.105/" />

      </soap:Body>

    </soap:Envelope>

     

    现在添加了header部分。

     

    .net web服务中为soap添加附件。这里为什么说.net web服务呢?

    这里说明一下web服务的概念:web service是基于xmlhttp的一种服务,它的通信协议主要基于SOAP(这是缩写应该全大写,但大家明白就行),通过WSDL来描述服务,通过UDDI来发布服务。

    Web服务不是只有.net才有,.net中提供的web服务相关的定义,发布,发现等,及生成代理,应用。这些只是.netweb服务的一种帮助,或说.net提供了一套web服务的工具,用于创建,发布和应用。

     

    Soap包中可以存放数据的位置可以是头,更重要且必须的是包体部分。那么对于附件,可以以格式化的数据存放于包体部分。

    现在以包体部分来存储一个文本文件,目的很明确,那么文本文件内容以怎样的格式存放于包体呢?

    第一种:文本文件中的内容以字串格式存在

     

    [WebMethod]

    public void SaveText(string strContent,string strFileName)

    {

    StreamWriter writer=File.CreateText("k:\\"+strFileName+".txt");

    writer.WriteLine(strContent);

    writer.Close();

    }

    这个方法将字串保存为utf-8的文本文件

     

    客户端:

    [Test]

    public void TestSaveText()

    {

    StreamReader sr = new StreamReader

    (@"k:\client.txt",Encoding.Default);

        string strTemp = sr.ReadToEnd();

        sr.Close();

     

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

        client.SaveText(strTemp, "server");

    }

    gb2312文本中读取内容,然后存在包体中向服务传递。可以看下现在的包的内容:

    <?xml version="1.0" encoding="utf-8"?>

    <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>

        <SaveText xmlns="http://192.168.1.105/">

          <strContent>杩欐槸娴嬭瘯锛乤bc</strContent>

          <strFileName>server</strFileName>

        </SaveText>

      </soap:Body>

    </soap:Envelope>

     

    其中乱码部分就是内容(乱码其实并不乱),可以所这部分拷贝到一个utf-8编码下的记事本中,然后另存为gb2312格式,可以看到认识的汉字了。

    内容就是:这是测试!abc

     

    第二种,二进制文件例如图片以base64编码存放

    其实这个文件可以直接以二进制格式来传递,但如果要保存这个包,那么须对持久化的数据进行双向的格式化,使它的数据格式不会在转化时丢失或增加,在消息1中:

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

    给出了通过base64和支持8位字符编码的28591页的字符集ISO8859-1

     

    (一)base64来存放二进制图片

    服务端:

    [WebMethod]

    public void SaveImages(string strBase64Content)

    {

    //ISO

    byte[] bb = Convert.FromBase64String(strBase64Content);//iso字节

    Encoding encoding = Encoding.GetEncoding(28591);

    string strReturn = encoding.GetString(bb);

     

    FileStream fs = File.Create(@"k:\soapPic.gif");

    fs.Write(bb, 0, bb.Length);

    fs.Close();

    }

     

    客户端:

    [Test]

    public void TestSaveImage()

    {

        //1 iso

        Encoding _encoding = Encoding.GetEncoding(28591);

        StreamReader sr = new StreamReader(@"k:\x1.gif", _encoding);

        string strTemp = sr.ReadToEnd();

        sr.Close();

     

        //2 base64

        byte[] bb = _encoding.GetBytes(strTemp);

        string strBase64 = Convert.ToBase64String(bb);

     

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

        client.SaveImages(strBase64);

    }

    看一下现在的soap包:

    <?xml version="1.0" encoding="utf-8"?>

    <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>

        <SaveImages xmlns="http://192.168.1.105/">

          <strBase64Content>DggAOw==</strBase64Content>

        </SaveImages>

      </soap:Body>

    </soap:Envelope>

     

    其中的粗体部分就是图片的内容,我省略了大部分,只留个小段。

     

    (二)以二进制来传递但不保存文本

    在进行base64的转换过程中要有性能损失,多一步就多消耗。因为现在不用对图片进行文本保存,那么这种持久不必要考虑,只要把图片存储下来就可以了。那么现在以二进制传递来存储图片。

    服务端:

    [WebMethod]

    public void SaveBinaryImages(byte[] bb)

    {

    FileStream fs = File.Create(@"k:\soapPicBinary.gif");

    fs.Write(bb, 0, bb.Length);

    fs.Close();

    }

     

    客户端:

    [Test]

    public void TestSaveBinaryImage()

    {

        FileStream fs = new FileStream(@"k:\x1.gif",FileMode.Open);

        byte[] bb=new byte[fs.Length];

         fs.Read(bb,0,bb.Length);  

        fs.Close();

     

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

        client.SaveBinaryImages(bb);

    }

     

    现在的soap包情况:

    <?xml version="1.0" encoding="utf-8"?>

    <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>

        <SaveBinaryImages xmlns="http://192.168.1.105/">

          <bb>DggAOw==</bb>

        </SaveBinaryImages>

      </soap:Body>

    </soap:Envelope>

     

    这个包我也省略了一部分。从上面两个包分析,原来,在.net web服务里,对包体中的附件的二进制附件传递是以base64编码来进行的,所以soap中包体中的附件的转换带来的是性能上的损失。

     

    在进行soap消息传递过程中,经常要把各种附件一起发送,而这些附件通过是二进制格式。在soap规范中有对附件的描述,那就是使用MIME类型以URI模式引用MIME部件。对于web服务的工具来说,并不是所有的工具都提供了对soap附件的支持,例如.net web服务。但微软推出了基于DIME的附件解决方案,并通过WSEweb服务增强)来支持web服务的MTOM消息优化传输,当然在WCF中更是支持MTOMMTOM 是一种机制,用来以原始字节形式传输包含 SOAP 消息的较大二进制附件,从而使所传输的消息较小。

    Base64编码以3个字节编码规则为4个字节,多出三分之一的容量,对于base64编码请见:

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

     

    soap消息包,信念xml格式的soap体消息,以及信封中未定义的但与消息有关的任意数据格式的其它实体。soap消息包通过MIMEMultipart/related媒体类型构建,每个部件都嵌入MIME边界(bundary,在Content-Type报头中定义)。每个MIME部件都有报头信息如:

    Content-Type:表示数据的类型

    Content Transfer-encoding:表示编码

    Content-ID:表示引用内容的标识符

    对于MIME消息的根部件要包含soap封套,且Content-type要设置为text/xml

     

    下边是一个带有MIME格式附件的soap包:

     

    Content-Type:text/xml; charset=UTF-8

    Content-Transfer-Encoding: binary

    Content-ID:<SOAP-ENV:Envelop>

      <?xml version="1.0" encoding="UTF-8"?>

      <soapenv:Envelope>

        <soapenv:Header>

        </soapenv:Header>

        <soapenv:Body>

        </soapenv:Body>

      </soapenv:Envelope>

     

    --==_Part_20081204084150203==

    Content-Type:text/plain

    Content-Transfer-Encoding:binary

    Content-ID:<attachment0.txt>

    aaaaaaaaaaaaaaaaaaaaaaaaaaa

    --==_Part_20081204084150203==

    Content-Type:image/jpeg

    Content-Transfer-Encoding:binary

    Content-ID:<attachment1.jpg>

    ......JFIF.....d.d.....C...

    --==_Part_20081204084150203==--

     

    以上就是一个完整的mime附件的soap包。

     

    博客园大道至简

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

    转载请注明:博客园

  • 相关阅读:
    应对高并发场景的redis加锁技巧
    Spring中@Transactional事务回滚(含实例具体解说,附源代码)
    计算机网络10--计算机网络体系结构简单介绍
    IIS身份验证的配置
    AMR音频文件格式分析
    IOS版本号被拒的经历
    两分钟读懂《成大事者不纠结》——读书笔记
    同一个TextView设置不同的颜色和大小
    似非而是的程序猿悖论---为什么救火比防火更加吃香?
    OS
  • 原文地址:https://www.cnblogs.com/jams742003/p/1701555.html
Copyright © 2011-2022 走看看