Я пытаюсь опубликовать файл на сервере ASP.NET WEB API (С#) с локальным Java-приложением. В основном я пытаюсь воспроизвести следующий код HTML в Java SE:
<form name="form1" method="post" enctype="multipart/form-data" action="http://localhost:50447/api/files/">
<div>
<label for="image1">Image File</label>
<input name="image1" type="file" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
Какой самый простой способ сделать это? Я бы хотел избежать использования Apache.. Что-то вроде:
String urlToConnect = "http://localhost:50447/api/files/";
String paramToSend = "";
File fileToUpload = new File("C:/Users/aa/Desktop/sample_signed.pdf");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
URLConnection connection = null;
try {
connection = new URL(urlToConnect).openConnection();
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
connection.setDoOutput(true); // This sets request method to POST.
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try {
writer = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"paramToSend\"");
writer.println("Content-Type: text/plain; charset=UTF-8");
writer.println();
writer.println(paramToSend);
writer.println("--" + boundary);
writer.println("Content-Disposition: form-data; name=\"fileToUpload\"; filename=\"sample_signed.pdf\"");
writer.println("Content-Type: text/plain; charset=UTF-8");
writer.println();
BufferedReader reader = null;
try {
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileToUpload), "UTF-8"));
} catch (UnsupportedEncodingException | FileNotFoundException e1) {
e1.printStackTrace();
}
try {
for (String line; (line = reader.readLine()) != null;) {
writer.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
writer.println("--" + boundary + "--");
} catch (UnsupportedEncodingException e2) {
e2.printStackTrace();
} catch (IOException e2) {
e2.printStackTrace();
} finally {
if (writer != null) writer.close();
}
// Connection is lazily executed whenever you request any status.
int responseCode = 0;
try {
responseCode = ((HttpURLConnection) connection).getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(responseCode);
Использование только URLConnections.. Этот код работает некорректно.. Он отправляет файл, но некоторый контент теряется, и я не знаю, почему.. Мой образец HTML работает отлично..
Вы можете мне помочь?
Благодарим вас за внимание, с наилучшими пожеланиями.
Решение. Другой подход, использующий DataOutputStream.
FileInputStream fileInputStream = new FileInputStream(absolutePath);
URL url = new URL("http://localhost:50447/api/files/");
// Open a HTTP connection to the URL
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true); // Allow Inputs
conn.setDoOutput(true); // Allow Outputs
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("uploaded_file", filename);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + fileName + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
// send multipart form data necesssary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
System.out.println(serverResponseMessage);
fileInputStream.close();
dos.flush();
dos.close();
Вы используете комбинацию чтения и записи, в то время как вы передаете двоичные данные. Вы должны использовать потоки при работе с двоичными данными.
Поэтому вместо BufferedReader используйте обычный InputStream, буферизованный для чтения файла, и не завершайте поток вывода, который вы получаете из URLConnection.
Чтение байтов вместо строк в цикле чтения. Поэтому замените часть, начинающуюся с BufferedReader, до окончательного момента, прежде чем писать границу:
OutputStream output = connection.getOutputStream();
InputStream fileIn = new FileInputStream(fileToUpload);
try {
byte[] buffer = new byte[4096];
int length;
while ((length = fileIn.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.flush();
} finally {
if (fileIn != null) try { fileIn.close(); } catch (IOException logOrIgnore) {}
}