POST 文件(作为二进制流)使用 java.net.HttpURLConnection 作为参数 file=<file binary stream>
POST file (as binary stream) using java.net.HttpURLConnection as a param file=<file binary stream>
我正在尝试使用 java.net.HttpURLConnection 将文件上传 (POST) 到端点,但我一直收到 http 代码 400(错误请求)。
我参考了
但问题是我需要将此文件作为请求正文参数 (file=) 发送。
注意:这些文件只有很小的尺寸 (4-5mb),所以我完全在内存中阅读它。
对应的curl请求为:
curl -X POST "API" -H "Content-Type: multipart/form-data" -F "file="
我正在使用的代码摘录:
Proxy webproxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("
<proxy host>", <proxy_port>));
HttpURLConnection http_conn = (HttpURLConnection)
url.openConnection(webproxy);
String authorization = getAuthorization(access_token);
http_conn.setRequestMethod("POST");
http_conn.setRequestProperty("Accept-Charset", "UTF-8");
http_conn.setRequestProperty("Authorization", authorization);
http_conn.setRequestProperty("Connection", "Keep-Alive");
http_conn.setRequestProperty("Content-Type", "multipart/form-data);
http_conn.setDoOutput(true);
http_conn.setDoInput(true);
DataOutputStream outputStream;
outputStream = new DataOutputStream(http_conn.getOutputStream());
File file_obj = new File(this.file);
byte[] allBytes = new byte[(int) file_obj.length()];
FileInputStream fileInputStream = new FileInputStream(file_obj);
outputStream.write("file=".getBytes("UTF-8")); <---Trying to add file param here
fileInputStream.read(allBytes);
outputStream.write(allBytes);
Post 我刚刚使用以下代码读取响应(适用于不同的 GET 请求):
InputStream inputStream = http_conn.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(inputStream));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
data = data + line;
}
注意:我很少使用 java,也不是很熟悉,所以请在您的回复中进行描述。
查看您的 curl 命令行时,它显示文件需要作为 multipart/form-data
请求发送。这实际上是一种在需要时格式化数据的复杂方法。
An example of the format you need to send is:
Headers:
Content-Type: multipart/form-data; boundary=AaB03x
Body:
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
目前,您的代码正在将文件作为 POST/GET 格式的请求发送,这不起作用,因为后端不希望如此。
为了解决这个问题,我们需要将源文件格式化成后端需要的格式,一旦知道"boundary"头选项只是一个随机生成的值,就更容易了发送请求。
String boundary = "MY_AWESOME_BOUNDARY"
http_conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
try(DataOutputStream outputStream = new DataOutputStream(http_conn.getOutputStream())) {
File file_obj = new File(this.file);
// Write form-data header
outputStream.write(("--" + boundary + "\r\n").getBytes("UTF-8"));
outputStream.write(("Content-Disposition: form-data; name=\"file\"; filename=\"file1.txt\"\r\n").getBytes("UTF-8"));
outputStream.write(("Content-Type: text/plain\r\n").getBytes("UTF-8"));
outputStream.write(("\r\n").getBytes("UTF-8"));
// Write form-data body
Files.copy(file_obj.toPath(), outputStream)
// Write form-data "end"
outputStream.write(("--" + boundary + "--\r\n").getBytes("UTF-8"));
}
// Read backend response here
try(InputStream inputStream = http_conn.getInputStream()) {
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(inputStream));
StringBuilder lines = new StringBuilder(); // StringBuilder is faster for concatination than appending strings
while ((line = bufferedReader.readLine()) != null) {
lines.append(line);
}
System.out.println(lines);
}
请注意,我使用了 "try-with-resource" 块,这些块确保在您使用完它们后关闭和处置任何外部资源,通常 OS 的开放资源限制非常低,与您的程序拥有的内存量相比,您的程序可能会出现奇怪的错误,这种错误只会在 运行 一段时间后或当用户在您的应用程序中执行某些操作时发生
以上对我不起作用,所以我切换到不同的包 (okhttp3),这是对我有用的:
File file_obj = new File(this.file);
String authorization = "my authorization string";
Proxy webproxy = new Proxy(Proxy.Type.HTTP, new
InetSocketAddress("proxy", <port>));
OkHttpClient client = new OkHttpClient.Builder().proxy(webproxy).build();
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", "filename",
RequestBody.create(MediaType.parse("application/octet-stream"), file_obj)).build();
Request request = new Request.Builder().header("Authorization", authorization).url(this.url).post(requestBody).build();
try (Response response = client.newCall(request).execute()){
if(!response.isSuccessful()) return "NA";
return (response.body().string());
}
我正在尝试使用 java.net.HttpURLConnection 将文件上传 (POST) 到端点,但我一直收到 http 代码 400(错误请求)。
我参考了
但问题是我需要将此文件作为请求正文参数 (file=) 发送。
注意:这些文件只有很小的尺寸 (4-5mb),所以我完全在内存中阅读它。
对应的curl请求为:
curl -X POST "API" -H "Content-Type: multipart/form-data" -F "file="
我正在使用的代码摘录:
Proxy webproxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("
<proxy host>", <proxy_port>));
HttpURLConnection http_conn = (HttpURLConnection)
url.openConnection(webproxy);
String authorization = getAuthorization(access_token);
http_conn.setRequestMethod("POST");
http_conn.setRequestProperty("Accept-Charset", "UTF-8");
http_conn.setRequestProperty("Authorization", authorization);
http_conn.setRequestProperty("Connection", "Keep-Alive");
http_conn.setRequestProperty("Content-Type", "multipart/form-data);
http_conn.setDoOutput(true);
http_conn.setDoInput(true);
DataOutputStream outputStream;
outputStream = new DataOutputStream(http_conn.getOutputStream());
File file_obj = new File(this.file);
byte[] allBytes = new byte[(int) file_obj.length()];
FileInputStream fileInputStream = new FileInputStream(file_obj);
outputStream.write("file=".getBytes("UTF-8")); <---Trying to add file param here
fileInputStream.read(allBytes);
outputStream.write(allBytes);
Post 我刚刚使用以下代码读取响应(适用于不同的 GET 请求):
InputStream inputStream = http_conn.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(inputStream));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
data = data + line;
}
注意:我很少使用 java,也不是很熟悉,所以请在您的回复中进行描述。
查看您的 curl 命令行时,它显示文件需要作为 multipart/form-data
请求发送。这实际上是一种在需要时格式化数据的复杂方法。
An example of the format you need to send is:
Headers:
Content-Type: multipart/form-data; boundary=AaB03x
Body:
--AaB03x Content-Disposition: form-data; name="files"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --AaB03x--
目前,您的代码正在将文件作为 POST/GET 格式的请求发送,这不起作用,因为后端不希望如此。
为了解决这个问题,我们需要将源文件格式化成后端需要的格式,一旦知道"boundary"头选项只是一个随机生成的值,就更容易了发送请求。
String boundary = "MY_AWESOME_BOUNDARY"
http_conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
try(DataOutputStream outputStream = new DataOutputStream(http_conn.getOutputStream())) {
File file_obj = new File(this.file);
// Write form-data header
outputStream.write(("--" + boundary + "\r\n").getBytes("UTF-8"));
outputStream.write(("Content-Disposition: form-data; name=\"file\"; filename=\"file1.txt\"\r\n").getBytes("UTF-8"));
outputStream.write(("Content-Type: text/plain\r\n").getBytes("UTF-8"));
outputStream.write(("\r\n").getBytes("UTF-8"));
// Write form-data body
Files.copy(file_obj.toPath(), outputStream)
// Write form-data "end"
outputStream.write(("--" + boundary + "--\r\n").getBytes("UTF-8"));
}
// Read backend response here
try(InputStream inputStream = http_conn.getInputStream()) {
BufferedReader bufferedReader = new BufferedReader(new
InputStreamReader(inputStream));
StringBuilder lines = new StringBuilder(); // StringBuilder is faster for concatination than appending strings
while ((line = bufferedReader.readLine()) != null) {
lines.append(line);
}
System.out.println(lines);
}
请注意,我使用了 "try-with-resource" 块,这些块确保在您使用完它们后关闭和处置任何外部资源,通常 OS 的开放资源限制非常低,与您的程序拥有的内存量相比,您的程序可能会出现奇怪的错误,这种错误只会在 运行 一段时间后或当用户在您的应用程序中执行某些操作时发生
以上对我不起作用,所以我切换到不同的包 (okhttp3),这是对我有用的:
File file_obj = new File(this.file);
String authorization = "my authorization string";
Proxy webproxy = new Proxy(Proxy.Type.HTTP, new
InetSocketAddress("proxy", <port>));
OkHttpClient client = new OkHttpClient.Builder().proxy(webproxy).build();
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", "filename",
RequestBody.create(MediaType.parse("application/octet-stream"), file_obj)).build();
Request request = new Request.Builder().header("Authorization", authorization).url(this.url).post(requestBody).build();
try (Response response = client.newCall(request).execute()){
if(!response.isSuccessful()) return "NA";
return (response.body().string());
}