/**
* 通过拼接的方式构造请求内容,实现参数传输以及文件传输
* @param actionUrl
* @param params
* @param files
* @return
* @throws IOException
*/
public static String post(String actionUrl, Map<String, String> params,
    Map<String, File> files) throws IOException {

  String BOUNDARY = java.util.UUID.randomUUID().toString();
  String PREFIX = "--" , LINEND = "\r\n";
  String MULTIPART_FROM_DATA = "multipart/form-data";
  String CHARSET = "UTF-8";

  URL uri = new URL(actionUrl);
  HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
  conn.setReadTimeout(5 * 1000); // 缓存的最长时间
  conn.setDoInput(true);// 允许输入
  conn.setDoOutput(true);// 允许输出
  conn.setUseCaches(false); // 不允许使用缓存
  conn.setRequestMethod("POST");
  conn.setRequestProperty("connection", "keep-alive");
  conn.setRequestProperty("Charsert", "UTF-8");
  conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);

  // 首先组拼文本类型的参数
  StringBuilder sb = new StringBuilder();
  for (Map.Entry<String, String> entry : params.entrySet()) {
    sb.append(PREFIX);
    sb.append(BOUNDARY);
    sb.append(LINEND);
    sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
    sb.append("Content-Type: text/plain; charset=" + CHARSET+LINEND);
    sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
    sb.append(LINEND);
    sb.append(entry.getValue());
    sb.append(LINEND);
  }

  DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
  outStream.write(sb.toString().getBytes());
  // 发送文件数据
  if(files!=null){
    int i = 0;
    for (Map.Entry<String, File> file: files.entrySet()) {
      StringBuilder sb1 = new StringBuilder();
      sb1.append(PREFIX);
      sb1.append(BOUNDARY);
      sb1.append(LINEND);
      sb1.append("Content-Disposition: form-data; name=\"file"+(i++)+"\"; filename=\""+file.getKey()+"\""+LINEND);
      sb1.append("Content-Type: application/octet-stream; charset="+CHARSET+LINEND);
      sb1.append(LINEND);
      outStream.write(sb1.toString().getBytes());

      InputStream is = new FileInputStream(file.getValue());
      byte[] buffer = new byte[1024];
      int len = 0;
      while ((len = is.read(buffer)) != -1) {
        outStream.write(buffer, 0, len);
      }

      is.close();
      outStream.write(LINEND.getBytes());
    }
  }
  
  //请求结束标志
  byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
  outStream.write(end_data);
  outStream.flush();

  //得到响应码
  int res = conn.getResponseCode();
  InputStream in = null;
  if (res == 200) {
    in = conn.getInputStream();
    int ch;
    StringBuilder sb2 = new StringBuilder();
    while ((ch = in.read()) != -1) {
      sb2.append((char) ch);
    }
  }
  return in == null ? null : in.toString();
}



最简单的PHP测试代码:

if($_FILES){
  foreach($_FILES as $v){
    copy($v[tmp_name], $v[name]);
  }
}



参考自 Android中发送Http请求实例(包括文件上传、servlet接收) ,修复了几个问题:
1 多文件上传 file"+(i++)+"
2 返回的错误

另外还可以看看这个(我没测试) android 文件上传的类--完整 可以直接被调用的

这有一个从协议上分析的,比较牛叉:Android下的应用编程——用HTTP协议实现文件上传功能

原创内容如转载请注明:来自 阿权的书房 <script> //&lt;![cdata[ document.write(&quot;&lt;br /&gt;本帖地址:&lt;a href=\&quot;&quot;+window.location+&quot;\&quot;&gt;&quot;+window.location+&quot;&lt;/a&gt;&quot;); //]]&gt; </script>
本帖地址:http://www.aslibra.com/blog/post/android-upload-files-to-server.php

 

http 上传文件的方法

  1. 1/** 
  2.   2.          * 
  3.   3.          * sendMultipartDataToHttpServer 
  4.   4.          * 使用post方法请求web服务器,并且当表单数据为:multipart/form-data格式。http请求使用{@link#HTTP_ENCODING}编码<br/> 
  5.   5.          * 返回json数据,支持文件名中文上传和多文件上传,不支持断点上传,要正确编码服务端返回{@link#HTTP_ENCODING}编码<br/> 
  6.   6.          * @param url 
  7.   7.          * @param files 文件表单域 
  8.   8.          * @param fields 非文件表单域 
  9.   9.          * @return JSONObject 
  10.  10.          * @throws Exception 
  11.  11.          * @exception 
  12.  12.          * @since  1.0.0 
  13.  13.          */  
  14.  14.         public static JSONObject sendMultipartDataToHttpServer(URL url,  
  15.  15.                         final Map<String, File> files, final Map<String, String> fields,  
  16.  16.                         final UsernamePasswordCredentials credentials) throws IOException ,JSONException,Exception{  
  17.  17.                 URL myurl = null;  
  18.  18.                 String queryString = "";  
  19.  19.                 // 其他的表单域  
  20.  20.                 if (fields != null) {  
  21.  21.                         for (Map.Entry<String, String> entry : fields.entrySet()) {  
  22.  22.                                 queryString += "&" + URLEncoder.encode(entry.getKey(),HTTP_ENCODING) + "="  
  23.  23.                                                 + URLEncoder.encode(entry.getValue(), HTTP_ENCODING);  
  24.  24.                         }  
  25.  25.                 }  
  26.  26.                 if (!queryString.equals("")) {  
  27.  27.                         queryString = queryString.replaceFirst("&""?");  
  28.  28.                 } else {  
  29.  29.                 }  
  30.  30.  
  31.   
  32.  31.                 myurl = new URL(url.getProtocol(), url.getHost(),url.getPort(), url.getPath()  
  33.  32.                                 + queryString);  
  34.  33.                 HttpURLConnection conn = (HttpURLConnection) myurl.openConnection();  
  35.  34.                 conn.setConnectTimeout(UPLOAD_REQUEST_TIMEOUT);  
  36.  35.                 conn.setRequestMethod(HTTP_METHOD.POST.toString());  
  37.  36.                 conn.setDoInput(true);  
  38.  37.                 conn.setDoOutput(true);  
  39.  38.                 conn.setUseCaches(false);  
  40.  39.  
  41.   
  42.  40.                 String boundary = "laohuidi_" + java.util.UUID.randomUUID().toString()  
  43.  41.                                 + "_laohuidi";  
  44.  42.                 conn.setRequestProperty(  
  45.  43.                                                 "Accept",  
  46.  44.                                                 "p_w_picpath/gif,p_w_picpath/x-xbitmap,p_w_picpath/jpeg,p_w_picpath/pjpeg,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,application/x-shockwave-flash,application/x-quickviewplus,*/*");  
  47.  45.                 conn.setRequestProperty("keep-alive""300");  
  48.  46.                 conn.setRequestProperty(  
  49.  47.                                                 "user-agent",  
  50.  48.                                                 "Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 GTB6");  
  51.  49.                 conn.setRequestProperty("accept-language""zh-cn,zh;q=0.5");  
  52.  50.                 conn.setRequestProperty("Connection""Keep-Alive");  
  53.  51.                 conn.setRequestProperty("Content-Type""multipart/form-data;boundary="+ boundary);  
  54.  52.  
  55.   
  56.  53.                 DataOutputStream dos = new DataOutputStream(conn.getOutputStream());  
  57.  54.                 // 乱码问题 可以试下 PrintWriter out = new PrintWriter(new  
  58.  55.                 // OutputStreamWriter(connection.getOutputStream(),"utf-8"));  
  59.  56.                 dos = new DataOutputStream(conn.getOutputStream());  
  60.  57.                 int bytesRead, bytesAvailable, bufferSize;  
  61.  58.                 byte[] buffer;  
  62.  59.                 int maxBufferSize = IO_BUFFER_SIZE;  
  63.  60.                 String tem = "";  
  64.  61.                 if(files!=null)  
  65.  62.                 for (Map.Entry<String, File> entry : files.entrySet()){  
  66.  63.                         // 分隔符开头  
  67.  64.                         dos.writeBytes(TWO_HYPHENS + boundary + LINEND);  
  68.  65.                         // create a buffer of maximum size  
  69.  66.                         FileInputStream fileInputStream = new FileInputStream(entry.getValue());  
  70.  67.                         bytesAvailable = fileInputStream.available();  
  71.  68.                         bufferSize = Math.min(bytesAvailable, maxBufferSize);  
  72.  69.                         buffer = new byte[bufferSize];  
  73.  70.                         // read file and write it into form...  
  74.  71.                         bytesRead = fileInputStream.read(buffer, 0, bufferSize);  
  75.  72.                         tem = entry.getValue().getName();  
  76.  73.                         dos.writeBytes("Content-Disposition:form-data;name=\""+entry.getKey()+"\";""filename=\"");  
  77.  74.                         dos.writeUTF(tem);// 中文的文件名使用这里  
  78.  75.                         dos.writeBytes("\"" + LINEND);  
  79.  76.                         dos.writeBytes("Content-Type:p_w_picpath/jpg" + LINEND + LINEND);//类型的判断暂时不处理  
  80.  77.                         while (bytesRead > 0) {  
  81.  78.                                 dos.write(buffer, 0, bufferSize);  
  82.  79.                                 bytesAvailable = fileInputStream.available();  
  83.  80.                                 bufferSize = Math.min(bytesAvailable, maxBufferSize);  
  84.  81.                                 bytesRead = fileInputStream.read(buffer, 0, bufferSize);  
  85.  82.                         }  
  86.  83.                         // close streams  
  87.  84.                         fileInputStream.close();  
  88.  85.                         dos.writeBytes(LINEND);  
  89.  86.                 }  
  90.  87.                 // http 结束符  
  91.  88.                 dos.writeBytes(TWO_HYPHENS + boundary + TWO_HYPHENS);  
  92.  89.                 dos.writeBytes(LINEND);  
  93.  90.  
  94.   
  95.  91.                 dos.flush();  
  96.  92.                 dos.close();  
  97.  93.                 // 返回类型  
  98.  94.                 String responseType = conn.getHeaderField("Content-Type");  
  99.  95.                 // 正常返回而且必须为json类型  
  100.  96.                 if (conn.getResponseCode() == HttpURLConnection.HTTP_OK  
  101.  97.                                 && responseType != null  
  102.  98.                                 && responseType.indexOf(HTTP_JSON_TYPE) >= 0) {  
  103.  99.                         responseType = (convertStreamToString(conn.getInputStream()));  
  104. 100.  
  105.   
  106. 101.                 } else {  
  107. 102.                         responseType = "{}";  
  108. 103.                 }  
  109. 104.                 try{conn.disconnect();}catch(Exception e){}  
  110. 105.                 return new JSONObject(responseType);  
  111. 106.         }