zoukankan      html  css  js  c++  java
  • 笔谈HTTP Multipart POST请求上传文件

      公司一做iOS开发的同事用HTTP Multipart POST请求上传语音数据,但是做了两天都没搞定,项目经理找到我去帮忙弄下。以前做项目只用过get、post,对于现在这个跟服务器交互的表单请求我没有做过,但是程序员学习能力还是要有的,解决问题的方法和经验是很重要的。做过2000万用户量的业务sdk的开发,这点东西自然不在话下,优秀的程序员就是要有解决问题的能力与方法。

    1) 接口地址

    接口地址为:http://ip:port/upload

    2) UploadRequest消息定义

    Form表单参数定义如下

    固定name属性为

    参数名

    参数类型

    是否必填

    描述

    fileData

    字符串变长

    Y

    标识为文件数据

    其中的filename属性为

    原始文件名

    注意:该名称需要由上传端确保唯一性,此唯一只需要保证同一设备ID的情况下不重复即可

    DevIDs

    字符串变长

    Y

    设备ID(多个设备)

    Transport

    字符串变长

    Y

    音频编码信息,只支持G711A

    ClientID

    字符串变长

    Y

    客户端ID

    3) UploadResponse消息定义

    无扩展消息

     举例

    1) uploadRequest消息

    POST /spi/mediaul.do HTTP/1.1

    Accept: */*

    Accept-Language: zh-cn

    Content-Type: multipart/form-data; boundary=7da29f2d890386

    Host: abc.com

    Content-Length: 1516663(文件的实际总大小)

    Connection: Keep-Alive

    Cache-Control: no-cache 

    --7da29f2d890386

    Content-Disposition: form-data; name="DevIDs";

    660000000000000062349002a94658da, 66000000000000005550c42f9000e028

    --7da29f2d890386

    Content-Disposition: form-data; name="Transport";

    PCMA/8000/1

    --7da29f2d890386

    Content-Disposition: form-data; name="ClientID";

    XXXXXXX

    --7da29f2d890386

    Content-Disposition: form-data; name="fileData"; filename="XXX"

    Content-Type: application/octet-stream

    文件实际内容流数据

    --7da29f2d890386--

    2) uploadResponse消息

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

    <Message Version="1.0">

        <Header MsgType="UploadResponse" MsgSeq="11"/>

        <Result RetCode="0" RetDesc="操作成功"/>

    </Message>

      实现这个post表单请求,最重要的就是格式了,要知道 " " 与 " " 的区别,什么时候要换两行 或多行 ...,什么时候只能换一行 ,空格 不能漏掉,任何一个细节出现问题都会导致 the connection lost,这就是考察一个人的仔细程度。

      实现这个Multipart POST请求其实很简答的,细节决定成败,对于以前没有写个这种与服务器的表单交互请求的,那就只能在网上多搜集资料,认真比对了。所谓“熟读唐诗三百首,不会做诗也会吟”。我在网上看了一些资料,有的博客完全是误导人,这就要多看多对比,仔细甄别,做事与看人是同一道理,了解一个人不能凭一面之辞妄下结论。

      下面来看下我写的实现post与服务器进行表单数据交互的实现代码:

    //
    //  Created by dev.temobi on 15/5/7.
    //  Copyright (c) 2015年 dev.temobi. All rights reserved.
    //
    
    #import "ViewController.h"
    
    
    #define Boudary @"7da29f2d890386"
    
    //http://192.168.3.177:2800/upload
    #define iAddrIP @"192.168.3.177"
    #define iAddrPort 2800
    
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        [self uploadAudioToServiceSelectedDevice:@[@"86000123456884846234123456789007"] delegate:self];
        
    }
    
    - (void)uploadAudioToServiceSelectedDevice:(NSArray *)arrDevices delegate:(id)delegate//此delegate为 NSURLConnectionDelegate
    {
        NSString *url = [NSString stringWithFormat:@"http://%@:%i/upload",iAddrIP,iAddrPort];
        
        NSMutableData *body = [ NSMutableData data ];
        
        [body appendData:[[NSString stringWithFormat:@"--%@
    ", Boudary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="DevIDs"
    
    %@
    ", arrDevices[0]] dataUsingEncoding:NSUTF8StringEncoding]];
        
        [body appendData:[[NSString stringWithFormat:@"--%@
    ", Boudary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="Transport"
    
    %@
    ", @"PCMA/8000/1"] dataUsingEncoding:NSUTF8StringEncoding]];
        
        [body appendData:[[NSString stringWithFormat:@"--%@
    ", Boudary] dataUsingEncoding:NSUTF8StringEncoding]];
        NSString *TM_SDK_NULL_STRING = @"";
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="ClientID"
    
    %@
    ", TM_SDK_NULL_STRING] dataUsingEncoding:NSUTF8StringEncoding]];
        
        [body appendData:[[NSString stringWithFormat:@"--%@
    ", Boudary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="fileData"; filename="aaaaa.pcma"
    "] dataUsingEncoding:NSUTF8StringEncoding]]; // --注意只有一个
    
        [body appendData:[[NSString stringWithFormat:@"Content-Type: application/octet-stream
    
    "] dataUsingEncoding:NSUTF8StringEncoding]]; // --注意有两个
    
    
    
        NSString *RecordAudioFilePath = [[NSBundle mainBundle] pathForResource:@"aaaaa" ofType:@"pcma"];
        NSData *fileData = [NSData dataWithContentsOfFile:RecordAudioFilePath]; // ------语音数据---------
        [body appendData:fileData];
        [body appendData:[[NSString stringWithFormat:@"
    --%@--
    ", Boudary] dataUsingEncoding:NSUTF8StringEncoding]]; // ------注意分隔符Boudary前后各有一个
    ---------
        
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
        [request setTimeoutInterval:0];
        [request setValue:@"zh-cn" forHTTPHeaderField:@"Accept-Language"];
        [request setValue:[NSString stringWithFormat:@"%lu",(unsigned long)body.length] forHTTPHeaderField:@"Content-Length"];
        [request setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"];
        [request setValue:@"Keep-Alive" forHTTPHeaderField:@"Connection"];
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", Boudary] forHTTPHeaderField:@"Content-Type"];
        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:body];
        
        NSError *error = nil;
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
        if (data == nil) {
            NSLog(@"send request failed: %@", error);
        }
        
        [request release];
        
        NSString *response = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"response: %@", response);
        [response release]; }

      与服务器交互的响应结果如下:

    2015-05-08 10:10:11.834 PostDataToServer[4584:1627837] response: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <Message>
        <Header MsgSeq="0" MsgType="UploadResponse"/>
        <Result RetCode="200"/>
    </Message>

      就是这么简单,语音数据成功上传给服务器了。

      完整工程PostDataToServer 的下载地址为:http://pan.baidu.com/s/1qWkKnta

  • 相关阅读:
    MT【111】画图估计
    MT【110】巧设法向量解决距离问题
    a++为啥不能用作左值
    qt之正则表达式
    QtWebkit中如何将网页内容转为图片
    数字图像去雾快速算法
    基于AdaBoost的人脸检测
    谈谈自动瘦脸和自动眼睛放大算法
    QT_opengl_gluPerspective没有定义的处理方法
    OpenGL框架+QT版
  • 原文地址:https://www.cnblogs.com/sunminmin/p/4487042.html
Copyright © 2011-2022 走看看