zoukankan      html  css  js  c++  java
  • Android Http POST文件上传之-----RFC1867协议


    RFC1867协议介绍
               RFC1867协议主要是在HTTP协议的基础上为INPUT标签添加了file属性。同一时候限定了Form的method必须为POST,ENCTYPE必须为multipart/form-data。 其他属性标签, <INPUT TYPE=file>标记能够有一个VALUE属性来指定默认的文件名 能够用“SIZE=宽,高”来指定SIZE属性 。

    multipart/form-data

           multipart/form-data的媒体内容遵从RFC 1521所规定的多部分的数据流规则。

    它主要被用来描写叙述表单填写后返回的数据。在一个表单中(这里指的是HTML,当然其它一些应用也可 能使用表单),有一系列字段提供给用户进行填写。每一个字段都有自己的名字。

    在一个确定 的表单中。每一个名字都是唯一的。  
           multipart/form-data由多个部分组成,每一部分都有一个content-disposition标题头,它的 值是"form-data"。它的属性指明了其在表单内的字段名。举例来说,'content-disposition:  form-data; name="xxxxx"',这里的xxxxx就是相应于该字段的字段名。假设字段名包括非 ASCII码字符的话。还应该依照RFC 1522里面所规定的方法进行编码。

     
            对全部的多部分MIME类型来说,每一部分有一个可选的Content-Type,默认的值是 text/plain。假设文件的内容是通过表单填写上传返回的话。那么输入的文件就被定义为 application/octet-stream,或者,假设知道是什么类型的话,就定义为对应的媒体类型。如 果一个表单返回多个文件,那么它们就作为multipart/form-data中所结合的multipart/mixed 被返回。  
    假设所传送的内容不符合默认的编码方式的话。该部分都将被编码,并加上 "content-transfer-encoding"的标题头。

     


    Android Post上传文件的实现

               Android POST方式上传文件,能够基于通过 RFC1867协议来实现。

    	/**
    	 * 
    	 * @param urlPath
    	 * @param params
    	 *            map 參数 <參数名称 , 參数值>
    	 * @param fileParams
    	 *            map 文件类型 參数 <參数名称 , 文件路径>
    	 * 
    	 */
    	public String postFile(String urlPath, Map<String, Object> params,
    			Map<String, String> fileParams) throws FileNotFoundException {
    		String PREFIX = "--"; // 前缀
    		String LINE_END = "
    "; // 换行
    		String BOUNDARY = UUID.randomUUID().toString(); // 边界标识
    		URL url;
    		HttpURLConnection connection;
    		try {
    
    
    			url = new URL(urlPath);
    
    
    			connection = (HttpURLConnection) url.openConnection();
    			// 设置超时时间
    			connection.setReadTimeout(readTimeOut);
    			connection.setConnectTimeout(connectTimeOut);
    			// 请求方式
    			connection.setRequestMethod("POST");
    			connection.setRequestProperty("X-Requested-With", "XMLHttpRequest");
    			// 开启输入流
    			connection.setDoInput(true);
    			// 开启输出流
    			connection.setDoOutput(true);
    			// 关闭缓存
    			connection.setUseCaches(false);
    			// 设置编码
    			connection.setRequestProperty("Charset", "utf-8");
    			connection.setRequestProperty("connection", "keep-alive");
    			connection.setRequestProperty("user-agent",
    					"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
    			// 设置内容类型及定义BOUNDARY
    			connection.setRequestProperty("Content-Type", "multipart/form-data"
    					+ ";boundary=" + BOUNDARY);
    
    
    			// 获取输出流
    			DataOutputStream dos = new DataOutputStream(
    					connection.getOutputStream());
    			StringBuffer sb = null;
    
    
    			String result = "";
    			String paramStr;
    			// 发送非文件參数
    			if (mParams != null && mParams.size() > 0) {
    
    
    				Iterator<String> it = mParams.keySet().iterator();
    				while (it.hasNext()) {
    					sb = null;
    					sb = new StringBuffer();
    					String key = it.next();
    					Object value = mParams.get(key);
    					sb.append(PREFIX).append(BOUNDARY).append(LINE_END);
    					sb.append("Content-Disposition: form-data; name="")
    							.append(key).append(""").append(LINE_END)
    							.append(LINE_END);
    					sb.append(value).append(LINE_END);
    					paramStr = sb.toString();
    
    
    					dos.write(paramStr.getBytes());
    					dos.flush();
    				}
    			}
    			paramStr = null;
    			// 发送文件參数,读取文件流写入post输出流
    			if (mFileParams != null && !mFileParams.isEmpty()) {
    
    
    				Iterator<Entry<String, String>> fileIter = mFileParams
    						.entrySet().iterator();
    
    
    				while (fileIter.hasNext()) {
    					sb = null;
    					sb = new StringBuffer();
    					Entry<String, String> entry = fileIter.next();
    					String fileKey = entry.getKey();
    					String filePath = entry.getValue();
    
    
    					File file = new File(filePath);
    
    
    					if (file.exists() == false) {
    
    
    						throw new FileNotFoundException();
    					}
    					// 设置边界标示,设置 Content-Disposition头传入文件流
    
    
    					sb.append(PREFIX).append(BOUNDARY).append(LINE_END);
    					sb.append("Content-Disposition:form-data; name=""
    							+ fileKey + ""; filename="" + file.getName()
    							+ """ + LINE_END);
    					sb.append("Content-Type:" + CONTENT_TYPE + LINE_END);
    					sb.append(LINE_END);
    					dos.write(sb.toString().getBytes());
    
    
    					InputStream is = new FileInputStream(file);
    
    
    					byte[] bytes = new byte[1024];
    					int len = 0;
    
    
    					while ((len = is.read(bytes)) != -1) {
    
    
    						dos.write(bytes, 0, len);
    
    
    					}
    					is.close();
    					dos.write(LINE_END.getBytes());
    
    
    					dos.flush();
    				}
    				byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END)
    						.getBytes();
    				dos.write(end_data);
    				dos.flush();
    			}
    			dos.close();
    			int res = getResponseCode();
    			// 返回成功
    			if (res == 200) {
    				InputStream input = conn.getInputStream();
    				StringBuffer sb1 = new StringBuffer();
    				int ss;
    				while ((ss = input.read()) != -1) {
    					sb1.append((char) ss);
    				}
    				result = sb1.toString();
    				return result;
    			} else {
    			}
    		} catch (MalformedURLException e) {
    			Log.i(TAG, "MalformedURLException error");
    		} catch (IOException e) {
    			Log.i(TAG, "IOException error");
    		}
    		return null;
    	}

    </pre><pre>
          文章地址 :http://blog.csdn.net/jmq_0000/article/details/30244297

    
       
    
  • 相关阅读:
    Neoj4安装使用教程
    毕业设计每日博客——第五周3
    毕业设计每日博客——第五周2
    不知道为什么,我就是被这个冒号迷惑了
    对items函数的理解
    关于运算符+的一点想法
    请使用迭代查找一个list中最小和最大值,并返回一个tuple
    Python中最常见括号()、[]、{}的区别
    ping和telnet的区别
    SQL注入原理
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6780711.html
Copyright © 2011-2022 走看看