Android'de HttpURLConnection kullanarak sunucumuza bir dosya POST yapmaya çalışıyorum, ancak getResponseCode çağrısı yalnızca kilitleniyor ve hiçbir zaman geri dönmez. Sorun, sunucu için çok büyük olan dosyadan kaynaklanıyor, bu yüzden sunucu, 413 (sunucu günlüklerinde görebildiğim) bir HTTP hata kodunu geri gönderiyor, ancak bizim cihazımızda, bu hiç alınmadığı gibi görünüyor. Bizim uygulamasında aşağıdaki kodu var:HttpURLConnection getResponseCode dönen değil
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;
}
Sadece tekrar etmek gerekirse, HttpURLConnection yanıt kodu almak için görünmüyor neden, bu yüklemeyi reddeden sunucu neden 'var sorun değildir. Hata ayıklayıcısına ayırırken, HttpURLConnection çıktı arabelleğini yazmaya çalışırken sıkışmış gibi görünüyor, ancak uygulama zaten çıktı arabelleği yazma işlemini bitirmeden önce sunucu yanıt kodunu göndermiş (sunucu, POST'u başlığa göre reddetti). Sunucu Nginx bir Node.JS örneğine iletiyor, eğer bu hiç yardımcı olmuyorsa, ancak 413'ü günlüklerde görebildiğim gibi, bunun uygulamanın şeyleri tarafında bir sorun olduğunu düşünüyorum.
int status = httpURLConnection.getResponseCode();
Hayır öyle değil. Sunucu, isteği okuyana kadar yanıt göndermez. Aksine herhangi bir beklenti yanlıştır. HttpURLConnection' ile ilgisi yok. – EJP
Sunucu, tüm gövdenin gönderilmesinden önce bir yanıt gönderiyor - yani, isteklerin üstbilgisini okuyor, isteğin tüm gövdesi gönderilmeden önce, gövdenin çok büyük olacağını ve yanıtı göndereceğini belirliyor. Bkz. [Bu cevap] (http://stackoverflow.com/a/13424453/1054890) –
@EJP Bu bağlantıya bir göz attınız mı? Cevabımın doğru olduğunu görebildiğim kadarıyla değil, eğer daha iyi bir açıklama almak için iyi olur. –