将文件从 Java 客户机上载到 HTTP 服务器
2022-08-31 13:00:56
我想将一些文件上传到HTTP服务器。基本上,我需要的是向服务器发出某种POST请求,其中包含一些参数和文件。我见过只是上传文件的例子,但没有找到如何传递其他参数。
执行此操作的最简单,最免费的解决方案是什么?有没有人有任何文件上传示例可供我研究?我已经在谷歌上搜索了几个小时,但是(也许这只是其中一天)找不到我需要的东西。最好的解决方案是不涉及任何第三方类或库。
我想将一些文件上传到HTTP服务器。基本上,我需要的是向服务器发出某种POST请求,其中包含一些参数和文件。我见过只是上传文件的例子,但没有找到如何传递其他参数。
执行此操作的最简单,最免费的解决方案是什么?有没有人有任何文件上传示例可供我研究?我已经在谷歌上搜索了几个小时,但是(也许这只是其中一天)找不到我需要的东西。最好的解决方案是不涉及任何第三方类或库。
您通常使用java.net.URLConnection
来触发HTTP请求。您通常还会对混合 POST 内容(二进制和字符数据)使用多部分/表单
数据编码。单击该链接,其中包含有关如何撰写请求正文的信息和示例。该规范在 RFC2388 中有更详细的描述。multipart/form-data
下面是一个启动示例:
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等第三方库时,此代码不那么冗长。
Apache Commons FileUpload正如一些人错误地建议的那样,这里只对服务器端感兴趣。您不能在客户端使用,也不需要它。
以下是使用Apache HttpClient的方法(此解决方案适用于那些不介意使用第三方库的人):
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);