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

  • 相关阅读:
    Java安全之JNDI注入
    Visual Studio 2019 升级16.8之后(升级.Net 5),RazorTagHelper任务意外失败
    .Net Core 3.1升级 .Net 5后出现代码错误 rzc generate exited with code 1.
    重走py 之路 ——普通操作与函数(三)
    重走py 之路 ——字典和集合(二)
    设计模式结(完结篇)
    重走py 之路 ——列表(一)
    RestfulApi 学习笔记——分页和排序(五)
    RestfulApi 学习笔记——查询与过滤还有搜索(五)
    Android开发 Error:The number of method references in a .dex file cannot exceed 64K.Android开发 Error:The number of method references in a .dex file cannot exceed 64K
  • 原文地址:https://www.cnblogs.com/sunminmin/p/4487042.html
Copyright © 2011-2022 走看看