私はAndroid上でHttpURLConnectionを使用してサーバーにファイルをPOSTしようとしていますが、getResponseCodeコールはハングして返されません。この問題はファイルがサーバーにとって大きすぎることに起因しているため、サーバーは413というHTTPエラーコードを返します(サーバーログに表示されます)。しかし、私たちのデバイスではこれが受信されないようです。私たちのアプリで次のコードを持っている:HttpURLConnectionのは、応答コードをピックアップしていないようだ、なぜHttpURLConnection getResponseCodeが返されない
public FileUploadUtility(URL requestURL, File uploadFile) throws IOException
{
file = uploadFile;
String fileName = uploadFile.getName();
httpURLConnection = (HttpURLConnection) requestURL.openConnection();
httpURLConnection.setUseCaches(false);
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type", URLConnection.guessContentTypeFromName(fileName));
//httpURLConnection.setRequestProperty("Content-Length", Long.toString(fileSize));
long fileSize = uploadFile.length();
httpURLConnection.setFixedLengthStreamingMode(fileSize);
outputStream = httpURLConnection.getOutputStream();
}
/**
* Completes the request and receives response from the server.
*
* @return a list of Strings as response in case the server returned
* status OK, otherwise an exception is thrown.
* @throws IOException
*/
public String finish(ProgressListener progressListener) throws IOException, HTTPErrorCodeException
{
try (FileInputStream inputStream = new FileInputStream(file))
{
byte[] buffer = new byte[100 * 1024];
int bytesRead;
long fileSize = file.length();
int total = 0;
while ((bytesRead = inputStream.read(buffer)) != -1)
{
outputStream.write(buffer, 0, bytesRead);
total += bytesRead;
if(fileSize > 0)
{
progressListener.fileUploadProgress((float)total/(float)fileSize);
}
}
outputStream.flush();
}
catch (Exception e)
{
e.printStackTrace();
throw new IOException("Error uploading file: " + e.getMessage());
}
String response;
// Checks server's status code first
int status = httpURLConnection.getResponseCode();
if (status == HttpURLConnection.HTTP_OK)
{
try (BufferedReader reader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())))
{
StringBuilder builder = new StringBuilder();
String output;
while ((output = reader.readLine()) != null)
{
builder.append(output);
}
response = builder.toString();
Log.i("Server response body", response);
}
httpURLConnection.disconnect();
httpURLConnection = null;
}
else
{
String serverResponseMessage = httpURLConnection.getResponseMessage();
Log.i("Server Response Message", serverResponseMessage);
try (BufferedReader responseReader = new BufferedReader(new InputStreamReader((httpURLConnection.getInputStream()))))
{
StringBuilder builder = new StringBuilder();
String output;
while ((output = responseReader.readLine()) != null)
{
builder.append(output);
}
Log.i("Server response body", builder.toString());
}
catch (Exception e)
{
e.printStackTrace();
}
try (BufferedReader errorReader = new BufferedReader(new InputStreamReader((httpURLConnection.getErrorStream()))))
{
StringBuilder builder = new StringBuilder();
String output;
while ((output = errorReader.readLine()) != null)
{
builder.append(output);
}
Log.i("Server error", builder.toString());
}
catch (Exception e)
{
e.printStackTrace();
}
throw new HTTPErrorCodeException(status);
}
return response;
}
ただ、繰り返しになるが、問題は「なぜ、サーバがアップロードを拒否している」されていない、それはです。デバッガに侵入すると、HttpURLConnectionが出力バッファの書き込みを試みたままになっているように見えますが、アプリケーションが出力バッファの書き込みを完了する前に、サーバはすでにレスポンスコードを送信しています(サーバがヘッダーに基づいてPOSTを拒否したため)。サーバーはNode.JSインスタンスへのNginx転送であり、それがまったく役立つならば、ログに413が表示されているので、アプリケーション側の問題だと思う。
int status = httpURLConnection.getResponseCode();
いいえ、それはありません。サーバーは要求を読み取るまで応答を送信しません。それとは逆の期待は間違っている。 'HttpURLConnection'とは何も関係ありません。 – EJP
サーバーは、本文全体が送信される前に応答を送信しています。つまり、要求からヘッダーを読み取り、本体が大きすぎると判断して応答を送信します。 [この回答を参照](http://stackoverflow.com/a/13424453/1054890) –
@EJPあなたはそのリンクを見ましたか?限り、私の答えは正しいですが、それがない場合は、より良い説明を得るために良いだろう。 –