将文件从 Java 客户端上传到 HTTP 服务器

新手上路,请多包涵

我想将一些文件上传到 HTTP 服务器。基本上我需要的是某种带有一些参数和文件的对服务器的 POST 请求。我已经看到了仅上传文件的示例,但没有找到如何传递其他参数。

这样做的最简单和免费的解决方案是什么?有人有我可以研究的文件上传示例吗?我已经在谷歌上搜索了几个小时,但是(也许这只是其中的一天)找不到我需要的确切内容。最好的解决方案是不涉及任何第三方类或库的东西。

原文由 Marius 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 596
2 个回答

您通常会使用 java.net.URLConnection 来触发 HTTP 请求。您通常还使用 multipart/form-data 混合 POST 内容(二进制和字符数据)的编码。单击该链接,它包含信息和如何 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 Client 之 类的 3rd 方库时,此代码不那么冗长。

Apache Commons FileUpload 正如一些错误的建议在这里只对 服务器端 感兴趣。您不能在客户端使用也不需要它。

也可以看看

原文由 BalusC 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是使用 Apache HttpClient 的方法(此解决方案适用于那些不介意使用第 3 方库的人):

     HttpEntity entity = MultipartEntityBuilder.create()
                       .addPart("file", new FileBody(file))
                       .build();

    HttpPost request = new HttpPost(url);
    request.setEntity(entity);

    HttpClient client = HttpClientBuilder.create().build();
    HttpResponse response = client.execute(request);

原文由 Emmanuel Bourg 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题