1. ホーム
  2. java

JavaクライアントからHTTPサーバーにファイルをアップロードする

2023-09-29 19:32:55

質問

私はHTTPサーバーにいくつかのファイルをアップロードしたいと思います。基本的に私が必要とするものは、いくつかのパラメータとファイルを持つサーバーへのある種のPOSTリクエストです。私は単にファイルをアップロードする例を見たことがありますが、追加のパラメータを渡す方法は見つかりませんでした。

これを行うための最も簡単で無料のソリューションは何ですか?どなたか、私が勉強できるようなファイル アップロードの例をお持ちではないでしょうか。数時間ググってみましたが、(たぶん、そのような日のうちの 1 日だけ) 私が必要とするものを正確に見つけられませんでした。最良の解決策は、サードパーティのクラスまたはライブラリを伴わないものでしょう。

どのように解決するのですか?

通常であれば java.net.URLConnection を使って HTTP リクエストを送ります。また、通常は multipart/form-data エンコーディングも使用します。リンクをクリックしてください。 multipart/form-data リクエスト・ボディを構成する方法についての情報と例が含まれています。この仕様の詳細については RFC2388 .

キックオフの例です。

String url = "http://example.com/upload";
String charset = "UTF-8";
String param = "value";
File textFile = new File("/path/to/file.txt");
File binaryFile = new File("/path/to/file.bin");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

try (
    OutputStream output = connection.getOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
) {
    // Send normal param.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
    writer.append(CRLF).append(param).append(CRLF).flush();

    // Send text file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + textFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
    writer.append(CRLF).flush();
    Files.copy(textFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    Files.copy(binaryFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // End of multipart/form-data.
    writer.append("--" + boundary + "--").append(CRLF).flush();
}

// Request is lazily fired whenever you need to obtain information about response.
int responseCode = ((HttpURLConnection) connection).getResponseCode();
System.out.println(responseCode); // Should be 200

Apache Commonsのようなサードパーティライブラリを使用する場合、このコードはより冗長ではありません。 HttpComponents クライアント .

Apache コモンズの ファイルアップロード においてのみ重要であることを示唆しています。 サーバサイド . クライアントサイドでは使用できませんし、必要ありません。

こちらもご覧ください