HTTP - POST を、HttpURLConnection で実行

Android で使用するケースがあるかも知れない、multipart/form-dataHTTP-POST 送信の実装を考えて、

URL文字列、送信するFileパスをキーにした、org.apache.http.NameValuePair のマップ
 (key=<input type="file" の name 、value=MIME-Type のNameValuePair )
Map<String,NameValuePair>

と、他のフォームデータの NameValuePair 配列でPOST要求するクラスを定義した

NameValuePair を使うので、Apache HttpComponents から、httpcore-4.2.jar が必要にはなる。

Android は、既にバンドルされてるので、特に持ってくる必要はない。

http://hc.apache.org/httpcomponents-client-ga/

import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;
import java.util.Random;
import java.net.HttpURLConnection;
import javax.net.ssl.HttpsURLConnection;
import org.apache.http.NameValuePair;
/**
 * MultiPostClient
 */

public class MultiPostClient {
   private String boundary;
   private String userAgent;

   public MultiPostClient(){
      this("Android");
   }
   public MultiPostClient(String userAgent){
      this.userAgent = userAgent;
   }

   /**
    * @param url String
    * @param filesMap key=FilePath value=NameValuePair (name=form-FieldName , value=MIME-Type)
    * @param messagePairs NameValuePair (name=form-FieldName value=message)
    */

   public void send(String url,Map<String,NameValuePair> filesMap,NameValuePair...messagePairs){
      URLConnection conn = null;
      boundary = createBoundary();
      try{
         conn = new URL(url).openConnection();
         conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
         conn.setRequestProperty("User-Agent", userAgent);
         if (url.startsWith("https")){
            *1;
         }
         // send post File
         String endBoundary = "\r\n--" + boundary + "--\r\n";
         for(String filePath : filesMap.keySet()){
            File file = new File(filePath);
            out.write( createBoundarFileInfo(file.getName(), filesMap.get(filePath)).getBytes() );
            FileInputStream fileInputStream = new FileInputStream(file);
            byte b = new byte[1024];
            int len = 0;
            while((len=fileInputStream.read(b,0,b.length)) > 0){
               out.write(b,0,len);
            }
            fileInputStream.close();
         }
         out.write(endBoundary.getBytes());
         out.flush();
         out.close();
         // 戻りを読み込む場合、InputStream で読み込む
         //InputStream is = conn.getInputStream();

      }catch(Exception e){
         // 例外処理
      }finally{
         if (conn != null ){
            if (url.startsWith("https")){
               ((HttpsURLConnection)conn).disconnect();
            }else{
               ((HttpURLConnection)conn).disconnect();
            }
         }
      }
   }
   protected String createBoundartMessage(NameValuePair pair){
      StringBuffer sb = new StringBuffer("\r\n--");
      sb.append(boundary);
      sb.append("\r\n");
      sb.append("Content-Disposition: form-data; name=\"");
      sb.append(pair.getName());
      sb.append("\"\r\n");sb.append("\r\n");
      sb.append(pair.getValue());
      return sb.toString();
   }

   /**
    * @param pair NameValuePair (name=form-FieldName , value=MIME-Type)
    */

   private String createBoundarFileInfo(String fileName,NameValuePair pair){
      StringBuffer sb = new StringBuffer("--").append(boundary).append("\r\n");
      sb.append("Content-Disposition: form-data; name=\"");
      sb.append(pair.getName());   // form-FieldName
      sb.append("\"; filename=\"");
      sb.append(fileName);
      sb.append("\"\r\n");
      sb.append("Content-Type: ");
      sb.append(pair.getValue());
      sb.append("\r\n\r\n");
      return sb.toString();
   }

   private final static char MULTIPART_CHARS =
      "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
      .toCharArray();

   protected String createBoundary() {
      StringBuilder buffer = new StringBuilder();
      Random rand = new Random();
      int count = rand.nextInt(11) + 30; // a random size from 30 to 40
      for(int i = 0; i < count; i++){
         buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
      }
      return buffer.toString();
   }

}

*1:HttpsURLConnection)conn).setRequestMethod("POST");
         }else{
            ((HttpURLConnection)conn).setRequestMethod("POST");
         }
         conn.setDoOutput(true);
         conn.connect();
         OutputStream out = conn.getOutputStream();
         // send post Message
         for(NameValuePair p : messagePairs){
            out.write(createBoundartMessage(p).getBytes(