28
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AndroidからHTTPのmultipart/form-dataを使ってデータをアップロードする

Last updated at Posted at 2014-11-13

AndroidのHTTP Clientとしてはorg.apache.httpにあるライブラリ群とjava.net.HttpURLConnectionがあるが,org.apache.httpは推奨されていない.さらにmultipart/form-dataを使ってファイルをアップロードするにはクラスがいくつか足らない.そこで,java.net.HttpURLConnectionを使ってファイルをアップロードする簡単なライブラリを書いてみた.コードはAndroid snippetsを参考に実装した.私の改変部分はMITライセンスでどうぞ.もとのAndroid SnippetsのコードはPublic Domainです.

package info.informationsea.apps;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.util.Map;
import java.util.UUID;

/**
 * Copyright (C) 2014 Yasunobu OKAMURA
 * MIT License
 */
public class HttpMultipartSender {
    private HttpMultipartSender(){} // cannot make instance

    // this function is implemented based on http://www.androidsnippets.com/multipart-http-requests
    public static void sendMultipart(HttpURLConnection connection, String filefield, File filepath, Map<String, String> textdata) throws IOException {

        final String twoHyphens = "--";
        final String boundary =  "*****"+ UUID.randomUUID().toString()+"*****";
        final String lineEnd = "\r\n";
        final int maxBufferSize = 1024*1024*3;

        DataOutputStream outputStream;

        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);

        connection.setRequestMethod("POST");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);

        outputStream = new DataOutputStream(connection.getOutputStream());
        outputStream.writeBytes(twoHyphens + boundary + lineEnd);
        outputStream.writeBytes("Content-Disposition: form-data; name=\"" + filefield + "\"; filename=\"" + filepath.getName() +"\"" + lineEnd);
        outputStream.writeBytes("Content-Type: application/octet-stream" + lineEnd);
        outputStream.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
        outputStream.writeBytes(lineEnd);

        FileInputStream fileInputStream = new FileInputStream(filepath);
        int bytesAvailable = fileInputStream.available();
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];

        int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        while(bytesRead > 0) {
            outputStream.write(buffer, 0, bufferSize);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        outputStream.writeBytes(lineEnd);

        for (Map.Entry<String, String> entry : textdata.entrySet()) {
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);
            outputStream.writeBytes("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + lineEnd);
            outputStream.writeBytes("Content-Type: text/plain"+lineEnd);
            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(entry.getValue());
            outputStream.writeBytes(lineEnd);
        }

        outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

        outputStream.close();
    }
}
28
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?