我正在尝试通过设备上的HTTP POST将文件上传到服务器。我有两个方法upload1和upload2。
Upload1 使用 HttpPost 类并且它可以正常工作,但是对于较大的文件,它会抛出内存异常。
Upload2 使用 HttpURLConnection ,但不起作用。 (我从服务器获得BAD REQUEST消息。)我希望upload2工作,因为它使用流来发送数据并且不会引发内存不足异常。 我查看了wireshark中的包,标题看起来是一样的,但是upload1的长度是380,upload2只有94.可能是什么问题?
private void upload1(File file) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url + "?recname="
+ fileName);
// ///////////////////////////////////////
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "---------------------------This is the boundary";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
FileInputStream fin = new FileInputStream(file);
byte audioData[] = new byte[(int) file.length()];
fin.read(audioData);
fin.close();
// Send a binary file
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""
+ fileName + "\"" + lineEnd);
dos.writeBytes("Content-Type: audio/mp4" + lineEnd);
dos.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
dos.writeBytes(lineEnd);
dos.write(audioData);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
dos.flush();
dos.close();
ByteArrayInputStream content = new ByteArrayInputStream(
baos.toByteArray());
BasicHttpEntity entity = new BasicHttpEntity();
entity.setContent(content);
entity.setContentLength(baos.toByteArray().length);
httppost.addHeader("Content-Type", "multipart/form-data; boundary="
+ boundary);
httppost.setEntity(entity);
// //////////////////////////////////
HttpResponse response = httpclient.execute(httppost);
BufferedReader reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
reader.close();
message = builder.toString();
System.out.println(message);
} catch (UnknownHostException e) {
message = "Error! Server is unreachable. Check you internet connection!";
} catch (Exception e) {
message = "error: " + e.toString();
}
}
/////////////////////////////////////////////// //////////////////////////////////////////
private void upload2(File file) {
HttpURLConnection connection = null;
String pathToOurFile = file.getPath();
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "---------------------------This is the boundary";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
try {
fileInputStream = new FileInputStream(new File(pathToOurFile));
URL server_url = new URL(url+ "?recname="
+ fileName);
connection = (HttpURLConnection) server_url.openConnection();
// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Enable POST method
connection.setRequestMethod("POST");
String bodyHeader = twoHyphens
+ boundary
+ lineEnd
+ "Content-Disposition: form-data; name=\"file\";filename=\""
+ fileName + "\"" + lineEnd + "Content-Type: audio/mp4"
+ lineEnd + "Content-Transfer-Encoding: binary" + lineEnd
+ lineEnd + twoHyphens + boundary + twoHyphens ;
byte[] bodyHeaderAray = bodyHeader.getBytes();
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("Expect", "100-continue");
// Content-Length
int bodyHeaderSize = (int) file.length() + bodyHeaderAray.length;
System.out.println("body header size: " + bodyHeaderSize);
// connection.setFixedLengthStreamingMode(bodyHeaderSize);
outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream
.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\""
+ fileName + "\"");
outputStream.writeBytes(lineEnd);
outputStream.writeBytes("Content-Type: audio/mp4" + lineEnd);
outputStream.writeBytes("Content-Transfer-Encoding: binary"
+ lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens
+ lineEnd);
fileInputStream.close();
outputStream.flush();
outputStream.close();
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
message = serverResponseMessage;
} catch (Exception ex) {
System.out.println(ex);
}
}
答案 0 :(得分:3)
根据您要上传文件的问题。您应该使用Multipart机制将文件上传到服务器。
httpclient-4.1.jar
httpcore-4.1.jar
httpmime-4.1.jar
apache-mime4j-0.6.1.jar
为此,您需要在项目中添加几个库,并将其用于HTTP连接和文件数据。
private boolean uploadFile(File mFile) {
boolean success = true;
String filename = mFile.getName();
MultipartEntity data_to_send = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
try {
data_to_send.addPart(
"name",
new StringBody(
filename.substring(filename.lastIndexOf("/") + 1)));
data_to_send.addPart("fileData", new FileBody(mFile));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
String responseData = ConsumeWebService.sendRequest(data_to_send,
Global.BASE_URL + serviceUrl);
if (TextUtils.isEmpty(responseData)
|| responseData.equals(ConsumeWebService.ERROR_CODE)) {
success = false;
}
} catch (Exception e) {
success = false;
e.printStackTrace();
}
return success;
}
public static String sendRequest(MultipartEntity data, String url) {
String response = "";
response = postData(url, data);
return response;
}
private static String postData(String url, MultipartEntity data) {
String strResponse = "";
try {
Log.d(Global.TAG, "Post URL is " + url);
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(data);
strResponse = httpClient.execute(httpPost,
new BasicResponseHandler());
} catch (UnsupportedEncodingException e) {
strResponse = ERROR_CODE;
e.printStackTrace();
} catch (ClientProtocolException e) {
strResponse = ERROR_CODE;
e.printStackTrace();
} catch (IOException e) {
strResponse = ERROR_CODE;
e.printStackTrace();
}
return strResponse;
}
答案 1 :(得分:0)
您可以按照this w3.org docs about forms自行构建POST请求。
我认为在 upload2 中,您缺少一个lineEnd:
....
outputStream.writeBytes("Content-Transfer-Encoding: binary"
+ lineEnd);
在此之后,您必须传输数据,并且在实际数据之前需要两个lineEnd,因此它应该是:
....
outputStream.writeBytes("Content-Transfer-Encoding: binary"
+ lineEnd + lineEnd);
为了读取文件并将它们放在multipart / form-data结构中,我建议你这样对我有用:
FileInputStream fileInputStream=new FileInputStream(file);
byte[] bytes= new bytes[fileInputStream.getChannel().size()];
fileInputStream.read(bytes);
fileInputStream.close();
outputStream.write(bytes);
outputStream.writeBytes(lineEnd);
希望它有所帮助。