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();
}
}