我正在尝试上传Photo并将JSON字符串传递给服务器。
我的猜测是我错误地计算了内容长度。但我不确定数学问题出在哪里。
有人可以帮我追踪我的错误吗?
我收到以下错误:
E / PhotoUpload:错误:预计14591字节但收到15183 java.net.ProtocolException:预计14591字节,但收到15183 at com.android.okhttp.internal.http.HttpConnection $ FixedLengthSink.write(HttpConnection.java:311) 在com.android.okio.RealBufferedSink.flush(RealBufferedSink.java:154) 在 com.android.okio.RealBufferedSink $ 1.flush(RealBufferedSink.java:137) 在java.io.FilterOutputStream.flush(FilterOutputStream.java:88)at java.io.DataOutputStream.flush(DataOutputStream.java:63)at com.mycompany.myapp.TakePhotoActivity $ BGUploadImage.doInBackground(TakePhotoActivity.java:381) 在 com.mycompany.myapp.TakePhotoActivity $ BGUploadImage.doInBackground(TakePhotoActivity.java:273)
E / PhotoUpload:错误:预计14591字节但收到15183 java.net.ProtocolException:预计14591字节,但收到15183 at com.android.okhttp.internal.http.HttpConnection $ FixedLengthSink.write(HttpConnection.java:311) 在com.android.okio.RealBufferedSink.flush(RealBufferedSink.java:154) 在 com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:769) 在 com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:405) 在 com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:349) 在 com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:203) 在 com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210) 在 com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:25) 在 com.mycompany.myapp.TakePhotoActivity $ BGUploadImage.doInBackground(TakePhotoActivity.java:393) 在 com.mycompany.myapp.TakePhotoActivity $ BGUploadImage.doInBackground(TakePhotoActivity.java:273) 在android.os.AsyncTask $ 2.call(AsyncTask.java:292)
public class BGUploadImage extends AsyncTask<String, Integer, Integer> {
int maxBufferSize = 1 * 256 * 1024;
int headerSize = 89;
String urlString = "http://www.mywebsite.com/someapi";
int fileSize = 0;
int infoSize = 0;
private int i;
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Integer... values) {
}
@Override
protected Integer doInBackground(String... file) {
Integer ret = 0;
HttpURLConnection conn = null;
DataOutputStream dos = null;
DataInputStream inStream = null;
String exsistingFileName = file[0];
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "---------------------------14737809831466499882746641449";
String json = JSONCalls.uploadImageJSON(thisCallKey);
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
try {
Log.i("PhotoUpload", "Start uploading file: " + file[0]);
FileInputStream fileInputStream = new FileInputStream(new File(exsistingFileName));
URL url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
fileSize = fileInputStream.available();
infoSize = fileSize + headerSize + file[0].length();
conn.setFixedLengthStreamingMode(infoSize);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
dos = new DataOutputStream(conn.getOutputStream());
//JSON PART
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name='params'" + lineEnd);
dos.writeBytes(json);
dos.writeBytes(lineEnd);
//MEDIA PART
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name = 'UploadedFile'; filename = '" + file[0] + "' " + 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);
int bytesSent = 0;
while (bytesRead > 0) {
if (bytesSent > 0) {
int pg = (bytesSent * 100) / infoSize;
publishProgress(pg);
}
bytesSent += bufferSize;
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);
//close streams
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
Log.e("PhotoUpload", "error: " + ex.getMessage(), ex);
ret = 1;
} catch (IOException ioe) {
Log.e("PhotoUpload", "error: " + ioe.getMessage(), ioe);
ret = 1;
}
try {
inStream = new DataInputStream(conn.getInputStream());
String str;
while ((str = inStream.readLine()) != null) {
Log.i("PhotoUpload", "Server Response" + str);
}
inStream.close();
} catch (IOException ioex) {
Log.e("PhotoUpload", "error: " + ioex.getMessage(), ioex);
ret = 1;
}
return ret;
}
@Override
protected void onPostExecute(Integer r) {
}
}
}
答案 0 :(得分:0)
我的猜测是我错误地计算了内容长度。
由于您根本没有计算内容长度或发送内容,因此很难理解这种猜测可能基于什么。
但是您的代码还有其他问题。你的副本循环:
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
int bytesSent = 0;
while (bytesRead > 0) {
if (bytesSent > 0) {
int pg = (bytesSent * 100) / infoSize;
publishProgress(pg);
}
bytesSent += bufferSize;
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
是一个不圣洁的混乱。 Java拷贝循环并不复杂:
byte[] buffer = new byte[8192];
int count;
while ((count = in.read(buffer)) > 0)
{
out,write(buffer, 0, count);
}
您不需要与文件大小相同的缓冲区。这只是在浪费空间。使用available()
作为文件大小的度量,或者为它分配足够大的缓冲区,在Javadoc中特别警告。这不是它的原因。 available()
的正确用法很少,而且不是其中之一。
flush()
之前的 close()
是多余的。