前提・実現したいこと
Java8とTomcat8.5を利用して、ファイルをアップロードするクライアントプログラムを作成しています。
大きいファイルにも対応するためHttpURLConnectionのsetFixedLengthStreamingModeを利用しています。
発生している問題・エラーメッセージ
サーバーからエラー(401等)が返される場合、
connection.getOutputStream().write(byte[] b)で書き込み中に、下記のエラーが発生します。
java.io.IOException: Error writing request body to server
エラーの内容を特定したいのですが、
connection.getResponseCode()やconnection.getInputStream()を参照すると、下記のエラーが発生してしまいます。
java.io.IOException: Incomplete output stream
エラーの内容を取得する方法はないでしょうか?
何卒、宜しくお願い致します。
該当のソースコード
Java
1import java.io.IOException; 2import java.io.InputStream; 3import java.io.OutputStream; 4import java.net.HttpURLConnection; 5import java.net.URL; 6import java.nio.file.Files; 7import java.nio.file.Path; 8import java.nio.file.Paths; 9import java.util.Base64; 10 11public class UploadTest { 12 public static void main(String[] args) { 13 try { 14 Path uploadFile = Paths.get("File Path"); 15 URL url = new URL("Server URL"); 16 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 17 connection.setDoOutput(true); 18 connection.setRequestMethod("POST"); 19 connection.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString("admin:adimnnn".getBytes())); 20 connection.setFixedLengthStreamingMode(Files.size(uploadFile)); 21 try (InputStream is = Files.newInputStream(uploadFile); 22 OutputStream os = connection.getOutputStream();) { 23 int len; 24 byte[] buf = new byte[8192]; 25 while ((len = is.read(buf, 0, buf.length)) > 0) { 26 os.write(buf, 0, len); 27 os.flush(); 28 } 29 } catch (Exception e) { 30 e.printStackTrace(); 31 } 32 System.out.println(connection.getResponseCode()); 33 } catch (IOException e) { 34 e.printStackTrace(); 35 } 36 } 37}
試したこと
大きいファイル(1GB)を指定した場合は以下の出力
java.io.IOException: Error writing request body to server at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.checkError(HttpURLConnection.java:3518) at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(HttpURLConnection.java:3501) at UploadTest.main(UploadTest.java:26) Suppressed: java.io.IOException: insufficient data written at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.close(HttpURLConnection.java:3540) at UploadTest.main(UploadTest.java:29) java.io.IOException: Incomplete output stream at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1505) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) at UploadTest.main(UploadTest.java:32)
小さいファイル(1KB)を指定した場合は以下の出力
401
すぐにOutputStreamへの書き込みが終わる為、
connection.getResponseCode()によりレスポンスを取得することができました。
補足情報(FW/ツールのバージョンなど)
JDK 8u131
Apache Tomcat Version 8.5.23
追記
OutputStreamを閉じてしまっているのが原因ではないかとご指摘いただいたので、送信部分下記のように変更して試してみました。
Java
1 try (InputStream is = Files.newInputStream(uploadFile); 2 OutputStream os = connection.getOutputStream();) { 3 int len; 4 byte[] buf = new byte[8192]; 5 try { 6 while ((len = is.read(buf, 0, buf.length)) > 0) { 7 os.write(buf, 0, len); 8 } 9 } catch (Exception e) { 10 e.printStackTrace(); 11 } 12 System.out.println(connection.getResponseCode()); 13 } catch (Exception e) { 14 e.printStackTrace(); 15 }
結果
java.io.IOException: Error writing request body to server at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.checkError(HttpURLConnection.java:3536) at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(HttpURLConnection.java:3519) at UploadTest.main(UploadTest.java:27) java.io.IOException: insufficient data written at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.close(HttpURLConnection.java:3558) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1521) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492) at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) at UploadTest.main(UploadTest.java:32)
レスポンスを取得しようとした時に、内部でcloseが呼ばれているようでした。
回答2件
あなたの回答
tips
プレビュー