zoukankan      html  css  js  c++  java
  • vc++调用web服务传输文件

    bool webService::UploadFile(LPWSTR appKey, LPWSTR fileName, const int len, unsigned char * buff)
    {
        
        try
         {
                     //SoapSerializer用于序列化(串行化),创建,封装SOAP消息.用来构建一个向Web服务发送的SOAP消息
                     ISoapSerializerPtr Serializer;
                     //SoapReader将SOAP消息解析为一个DOM模型,并提供一系列操作该DOM模型的方法
                     ISoapReaderPtr  Reader;
                     //SoapConnector在对象之间发送和接收SOAP消息的传输协议
                     ISoapConnectorPtr Connector;
    
                     IDataEncoderFactoryPtr encoderFc;
    
                     //创建一个Connector对象
                     Connector.CreateInstance(__uuidof(HttpConnector30));
                     //Web服务是由Property(HttpConnector的一个属性)指定的
                     //在处理这一属性时有件事情需要指定:我们引用的哪个属性以及该属性的值
                     //EndPointURL属性指定Web服务
                     Connector->Property["EndPointURL"] = "http://127.0.0.1/Services/UploadService.asmx?wsdl";//web服务的URL
                     ////////////////////////////////////////////////////////////////////////////
                     //Connector->Property[参数]说明,对大小写敏感
                    // AuthPassword: 端点认证用的口令。
                    // AuthUser:  端点认证用的用户名
                    // EndPointURL : 端点的URL
                    // ProxyPassword: 代理认证的口令
                    // ProxyPort : 代理服务器使用的端口
                    // ProxyServer : 代理服务器的IP地址或主机名
                    // ProxyUser : 代理认证的用户名
                    // SoapAction: HTTP头部中SoapAction中的值。这个属性只使用于低级API。它将忽略SoapClient接口(高级API)中的ConnectorProperty属性 。
                    // SSLClientCertificateName:指定使用Secure Sockets Layer (SSL)加密协议(如果存在,则该字符串标明用于SSL协议中的客户端证书)。语法如下:
                    //  [CURRENT_USER | LOCAL_MACHINE[store-name]]cert-name with the defaults being CURRENT_USERMY (与Microsoft Internet Explorer用法相同)。
                    // Timeout:  HttpConnector的超时限制,以毫秒为单位。
                    // UseProxy:  一个类型为布尔型的属性,表明是否使用代理服务器。缺省情况下,这一属性的值被设定为False,表明无需使用代理服务器。如果要使用代服务器,需要将该属性的值设置为True。如果将该属性的值设置为True, 而又没有设置ProxyServer属性,HttpConnector将使用IE中设置的代理服器。HttpConnector会忽略IE中的“不使用代理服务器”设置。 
                    // UseSSL:  表明是否使用了SSL的布尔型值。如果该属性被设置为True,则无论WSDL中是否指定了HTTP或HTTPS,HttpConnector对象都使用SSL连接。
                    //     如果该属性的值被设置为False,则只有在WSDL中指定了HTTPS的情况下, HttpConnector对象才会使用SSL连接
                    // 详细请参考:http://www.codesky.net/article/200504/62841.html
                     ///////////////////////////////////////////////////////////////////////////
                     
                     Connector->Connect();
                     //开始消息
                     Connector->Property["SoapAction"] = "http://tempuri.org/Append";
                     //开始SOAP消息
                     //在完成与Web服务的连接和其他的细节后,我们就可以调用向服务器发送SOAP信息的方法了,必须在调用SoapSerializer的其他方法之前调用该方法
                     Connector->BeginMessage();
                     //创建SoapSerializer对象
                     Serializer.CreateInstance(__uuidof(SoapSerializer30)); 
                     //将serializer连接到connector的输入字符串
                     //在与服务器连接前,SoapSerializer对象必须与SoapConnector对象连接。
                     //为了使这二个对象相互连接,我们需要调用SoapSerializer对象的Init方法,该方法需要一个参数InputStream(向服务器发送数据的流)
                     Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));
                     //创建SOAP消息
                     //开始处理SOAP消息,
                     //第一个参数是命名空间,缺省为SOAP-ENV,第二个参数定义URL,第三个参数定义Serialzier->startBody("")函数的编码方式。
                     Serializer->StartEnvelope("","","");
                     //开始处理Body元素,参数为URI的编码类型,缺省为NONE
                     Serializer->StartBody("");
                     //开始处理Body里的子元素
                     //第一个参数是元素名,第二个参数是URL,第三个参数是编码类型,第四个参数是元素的命名空间
                     ///////////Serializer->StartElement("HelloWorld",    "http://localhost:42782/","","soap");
                     Serializer->StartElement("Append",    "http://tempuri.org/","","soap");
                     //WebXml.com.cn是Web服务所属的名称空间(如果Web服务提供者没有指定名称空间,将会使用该默认名称空间)。
                    ///////// Serializer->StartElement("theCityName","","","soap");
                     //写入元素值,
                    ////////// Serializer->WriteString("郑州");
                     //上面的每个startXXX函数后都要有相应的endXXX函数来结尾
                    /////// Serializer->EndElement();
    
              
              //密钥(自定义web服务中的参数) Serializer->StartElement("appKey","","","soap"); Serializer->WriteString(appKey); Serializer->EndElement();           //文件名称(自定义web服务中的参数) Serializer->StartElement("fileName","","","soap"); Serializer->WriteString(fileName); Serializer->EndElement(); /********************传输二进制数据*****************************/ HRESULT hr = FALSE; encoderFc.CreateInstance(__uuidof(DataEncoderFactory30)); DWORD *len1=new DWORD; IDataEncoderPtr encoder=encoderFc->GetDataEncoder(L"base64"); encoder->raw_SizeToEncode(buff,len,len1); int lon = *len1; byte *data = new byte[lon+1]; hr=encoder->Encode(buff,len,data,len1); if(FAILED(hr)){ TRACE("Encode error! "); } int len2 = *len1; Serializer->StartElement("buffer","","","soap"); Serializer->WriteBuffer(len2, (byte*)data); delete len1; delete[] data; //结束 Serializer->EndElement(); /********************结束传输二进制数据*****************************/ Serializer->EndElement(); Serializer->EndBody(); Serializer->EndEnvelope(); //消息做完之后,连接器就调用endMessage()方法将消息发送到服务器 Connector->EndMessage(); //创建响应soap消息 Reader.CreateInstance(__uuidof(SoapReader30)); //OutPutStream来读取SoapReader对象中的信息 //将reader连接到connector的输出字符串 Reader->Load(_variant_t((IUnknown*)Connector->OutputStream),""); //将回应信息加载到SoapReader对象后,就可以用它的RpcResult属性来获取结果, //但是RpcResult并不直接返回结果,它返回Body的第一个实体元素 //然后用text属性读取该元素的属性值 return ((const char*)Reader->RpcResult->text)=="true"; /* printf("%s ",(const char*)Reader->RpcResult->text); MessageBoxA(NULL, Reader->RpcResult->text, "提示", MB_OK);*/ } catch(_com_error &e) { printf("%s",e.ErrorMessage()); } return 0; }

    2、web服务接口:

     /// <summary>
        /// 上传文件到服务器
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="buffer"></param>
        /// <returns></returns>
        [WebMethod]
        public bool Append(string fileName, string buffer,string appKey)
        {
          
            bool isAppend = true;
            try
            {
                fileName = Path.Combine(@"d:"+ Path.GetFileName(fileName) + ".txt");
                if (!File.Exists(fileName))
                {
                    CreateFile(fileName,appKey);
                }
                byte[] fileBuff = Convert.FromBase64String(buffer);
            
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                fs.Seek(0, SeekOrigin.End);
                fs.Write(fileBuff, 0, fileBuff.Length);
                fs.Close();
            }
            catch(Exception e)
            {
                string text = e.Message;
                isAppend = false;
            }
            return isAppend;
        }

    注意需要使用到:SoapToolkit3.0 开发包,开发的时候需要安装到本地,发布的时候不安装该客户端的步骤:

    1、修改头部文件:

    #import "msxml4.dll"  named_guids
    
    //FOR SOAPTIOOLKIT 3.0
    #import "MSSOAP30.dll" named_guids 
      exclude("IStream", "IErrorInfo", "ISequentialStream", "_LARGE_INTEGER", 
      "_ULARGE_INTEGER", "tagSTATSTG", "_FILETIME")

    2、将该目录下的所有文件复制到程序运行目录下“C:Program Files (x86)Common FilesMSSoapBinaries”,另外还需要复制msxml4r.dll msxml4.dll 两个文件。注意这两个文件创建时间都是2002-2-4其它时间的我这里报错

    3、然后再注册相关文件:

    最后在程序目录下执行:

    regsvr32 "MSSOAP30.dll" 
    regsvr32 "Resources1033MSSOAPR3.dll" 
    regsvr32 "WISC30.dll"
    regsvr32 "msxml4.dll"

    参考:https://www.1wanweb.com/post/vc2b2b60-mfc-soapsdke5bc80e58f91websesrvicee68993e58c85.aspx

  • 相关阅读:
    闭包 (Closure)
    RSA算法
    HTTPS
    SSH
    HDU1754 I hate it_线段树(入门级别)
    HDU1166 敌兵布阵_线段树
    c++运算符优先级表
    归并排序练习.
    HDU 1969 精度二分
    uva10944 状态压缩bfs or DP
  • 原文地址:https://www.cnblogs.com/lvlv/p/7526064.html
Copyright © 2011-2022 走看看