株式会社シベスピ 従業員ブログ

シベスピの社員ブログ。技術・想い・経験沢山書いていきます!

【WebAPI】multipart/form-dataでファイルをアップロードする 【Java】

SBです。

今回はJavaからWebAPIでファイルアップロードする方法を紹介しようと思います。
アップロード方法としてはmultipart/form-dataを使用します。

String urlStr = "https://httpbin.org/post";
String CRLF = "\r\n";
File file = new File("test.txt");
String boundary = UUID.randomUUID().toString();
HttpURLConnection con =null;
InputStream in = null;

try {
    // ファイルをbyte配列に変換
    byte[] fileByte = Files.readAllBytes(file.toPath());

    con = (HttpURLConnection) new URL(urlStr).openConnection();
    con.setRequestMethod("POST");
    con.setDoOutput(true);
    con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

    DataOutputStream request = new DataOutputStream(con.getOutputStream());

    request.writeBytes("--" + boundary + CRLF);
    request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"" + CRLF + CRLF);
    request.write(fileByte);
    request.writeBytes(CRLF);
    request.writeBytes("--" + boundary + "--" + CRLF);
    request.flush();
    request.close();

 // 結果を取得する
    int status = con.getResponseCode();

    if(status == HttpURLConnection.HTTP_OK) {
        // 正常系の場合はgetInputStream
        in = con.getInputStream();
    } else {
        // 異常系の場合はgetErrorStream
        in = con.getErrorStream();
    }
    // InputStream結果を出力(今回は割愛)
    read(in);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if(con != null) {
        con.disconnect();
    }
}


結果はこんな感じ

{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "test"
  }, 
  "form": {}, 
  "headers": {
    "Accept": "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2", 
    "Content-Length": "156", 
    "Content-Type": "multipart/form-data;boundary=c9f9f54a-30b7-4442-adc2-6c306e92c21d", 
    "Host": "httpbin.org", 
    "User-Agent": "Java/1.8.0_144", 
    "X-Amzn-Trace-Id": "Root=X-XXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX"
  }, 
  "json": null, 
  "origin": "XX.XXX.XXX.XX", 
  "url": "https://httpbin.org/post"
}

「"files": {}」内に格納されているため、無事にファイルが連携されていることが確認できました。

以下、簡単な解説
boundaryは簡単に言うと区切り文字になります。ランダムな文字列を使用します。
ファイルはバイト配列で送る必要があるため、readAllBytesメソッドでバイト配列に変換しています。(Java 7以降)

詰まりそうなポイントを書き出してみます。
・「name=\"file\";」の箇所は向こうで指定しているものを宣言する。
・文字列含めバイトで送る必要があるため、DataOutputStreamを使う。
・ファイルを書き出す直前の改行は2つ必要。
・閉じる直前には「"--" + boundary」ではなく「"--" + boundary + "--" + CRLF」を書き出す。


今回WebAPIの連携先として使っているhttps://httpbin.orgはWebAPIのテストに便利です。
もっと早く使うべきだった。。

以上、備忘録がてらのWebAPIのファイルアップロード方法紹介でした。