Android 使用 POST 和 HttpURLConnection 发送文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11766878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending files using POST with HttpURLConnection
提问by Mihai Todor
Since the Android developers recommendto use the HttpURLConnection
class, I was wondering if anyone can provide me with a good example on how to send a bitmap "file" (actually an in-memory stream) via POST to an Apache HTTP server. I'm not interested in cookies or authentication or anything complicated, but I just want to have a reliable and logic implementation. All the examples that I've seen around here look more like "let's try this and maybe it works".
由于 Android 开发人员建议使用HttpURLConnection
该类,我想知道是否有人可以为我提供一个很好的示例,说明如何通过 POST 将位图“文件”(实际上是内存中的流)发送到 Apache HTTP 服务器。我对 cookie 或身份验证或任何复杂的东西不感兴趣,但我只想有一个可靠的逻辑实现。我在这里看到的所有例子看起来更像是“让我们试试这个,也许它有效”。
Right now, I have this code:
现在,我有这个代码:
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL("http://example.com/server.cgi");
urlConnection = (HttpURLConnection) url.openConnection();
} catch (Exception e) {
this.showDialog(getApplicationContext(), e.getMessage());
}
finally {
if (urlConnection != null)
{
urlConnection.disconnect();
}
}
where showDialog should just display an AlertDialog
(in case of an invalid URL?).
其中 showDialog 应该只显示一个AlertDialog
(如果 URL 无效?)。
Now, let's say that I generate a bitmap like so: Bitmap image = this.getBitmap()
inside a control derived from View
and I want to send it via POST. What would be the proper procedure to achieve such a thing? What classes do I need to use? Can I use HttpPost
like in this example? If so, how would I construct the InputStreamEntity
for my bitmap? I would find it revolting to be required to first store the bitmap in a file on the device.
现在,假设我生成了一个像这样的位图:Bitmap image = this.getBitmap()
在派生自的控件中View
,我想通过 POST 发送它。实现这一目标的正确程序是什么?我需要使用哪些类?我可以HttpPost
在这个例子中使用like吗?如果是这样,我将如何InputStreamEntity
为我的位图构建?我会发现要求首先将位图存储在设备上的文件中是令人反感的。
I should also mention that I really need to send every unaltered pixel of the original bitmap to the server, so I can't convert it to JPEG.
我还应该提到,我真的需要将原始位图的每个未更改像素发送到服务器,因此我无法将其转换为 JPEG。
回答by Mihai Todor
I have no idea why the HttpURLConnection
class does not provide any means to send files without having to compose the file wrapper manually. Here's what I ended up doing, but if someone knows a better solution, please let me know.
我不知道为什么HttpURLConnection
该类不提供任何无需手动编写文件包装器即可发送文件的方法。这是我最终做的,但如果有人知道更好的解决方案,请告诉我。
Input data:
输入数据:
Bitmap bitmap = myView.getBitmap();
Static stuff:
静态的东西:
String attachmentName = "bitmap";
String attachmentFileName = "bitmap.bmp";
String crlf = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
Setup the request:
设置请求:
HttpURLConnection httpUrlConnection = null;
URL url = new URL("http://example.com/server.cgi");
httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("Connection", "Keep-Alive");
httpUrlConnection.setRequestProperty("Cache-Control", "no-cache");
httpUrlConnection.setRequestProperty(
"Content-Type", "multipart/form-data;boundary=" + this.boundary);
Start content wrapper:
启动内容包装器:
DataOutputStream request = new DataOutputStream(
httpUrlConnection.getOutputStream());
request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" +
this.attachmentName + "\";filename=\"" +
this.attachmentFileName + "\"" + this.crlf);
request.writeBytes(this.crlf);
Convert Bitmap
to ByteBuffer
:
转换Bitmap
为ByteBuffer
:
//I want to send only 8 bit black & white bitmaps
byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
for (int i = 0; i < bitmap.getWidth(); ++i) {
for (int j = 0; j < bitmap.getHeight(); ++j) {
//we're interested only in the MSB of the first byte,
//since the other 3 bytes are identical for B&W images
pixels[i + j] = (byte) ((bitmap.getPixel(i, j) & 0x80) >> 7);
}
}
request.write(pixels);
End content wrapper:
结束内容包装器:
request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary +
this.twoHyphens + this.crlf);
Flush output buffer:
刷新输出缓冲区:
request.flush();
request.close();
Get response:
得到回应:
InputStream responseStream = new
BufferedInputStream(httpUrlConnection.getInputStream());
BufferedReader responseStreamReader =
new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
responseStreamReader.close();
String response = stringBuilder.toString();
Close response stream:
关闭响应流:
responseStream.close();
Close the connection:
关闭连接:
httpUrlConnection.disconnect();
PS: Of course I had to wrap the request in private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String>
, in order to make the Android platform happy, because it doesn't like to have network requests on the main thread.
PS:当然我不得不把请求包裹在 中private class AsyncUploadBitmaps extends AsyncTask<Bitmap, Void, String>
,为了让Android平台开心,因为它不喜欢在主线程上有网络请求。
回答by Pencilcheck
I actually found a better way to send files using HttpURLConnection using MultipartEntity
我实际上找到了一种使用 MultipartEntity 使用 HttpURLConnection 发送文件的更好方法
private static String multipost(String urlString, MultipartEntity reqEntity) {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.addRequestProperty("Content-length", reqEntity.getContentLength()+"");
conn.addRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue());
OutputStream os = conn.getOutputStream();
reqEntity.writeTo(conn.getOutputStream());
os.close();
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return readStream(conn.getInputStream());
}
} catch (Exception e) {
Log.e(TAG, "multipart post error " + e + "(" + urlString + ")");
}
return null;
}
private static String readStream(InputStream in) {
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return builder.toString();
}
Assuming you are uploading an image with bitmap data:
假设您正在上传带有位图数据的图像:
Bitmap bitmap = ...;
String filename = "filename.png";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
ContentBody contentPart = new ByteArrayBody(bos.toByteArray(), filename);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("picture", contentPart);
String response = multipost("http://server.com", reqEntity);
And Voila! Your post data will contain picture field along with the filename and path on your server.
瞧!您的帖子数据将包含图片字段以及服务器上的文件名和路径。
回答by Jaydipsinh Zala
To upload file on server with some parameter using MultipartUtility
in simple way.
以MultipartUtility
简单的方式使用一些参数在服务器上上传文件。
MultipartUtility.java
多部分实用程序.java
public class MultipartUtility {
private final String boundary;
private static final String LINE_FEED = "\r\n";
private HttpURLConnection httpConn;
private String charset;
private OutputStream outputStream;
private PrintWriter writer;
/**
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
*
* @param requestURL
* @param charset
* @throws IOException
*/
public MultipartUtility(String requestURL, String charset)
throws IOException {
this.charset = charset;
// creates a unique boundary based on time stamp
boundary = "===" + System.currentTimeMillis() + "===";
URL url = new URL(requestURL);
Log.e("URL", "URL : " + requestURL.toString());
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
httpConn.setRequestProperty("User-Agent", "CodeJava Agent");
httpConn.setRequestProperty("Test", "Bonjour");
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
}
/**
* Adds a form field to the request
*
* @param name field name
* @param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
}
/**
* Adds a upload file section to the request
*
* @param fieldName name attribute in <input type="file" name="..." />
* @param uploadFile a File to be uploaded
* @throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
writer.append(LINE_FEED);
writer.flush();
}
/**
* Adds a header field to the request.
*
* @param name - name of the header field
* @param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).append(LINE_FEED);
writer.flush();
}
/**
* 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() throws IOException {
StringBuffer response = new StringBuffer();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response.toString();
}
}
To upload
you file
along with parameters.
给upload
你file
连同参数。
NOTE : put this code below in non-ui-thread to get response.
注意:将此代码放在下面的非 ui 线程中以获得响应。
String charset = "UTF-8";
String requestURL = "YOUR_URL";
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFormField("param_name_1", "param_value");
multipart.addFormField("param_name_2", "param_value");
multipart.addFormField("param_name_3", "param_value");
multipart.addFilePart("file_param_1", new File(file_path));
String response = multipart.finish(); // response from server.
回答by Georgevik
The solution of Jaydipsinh Zaladidn't work for me, I don't know why but it seems to be close to the solution.
Jaydipsinh Zala的解决方案对我不起作用,我不知道为什么,但它似乎接近解决方案。
So merging this one with the great solution and explanation of Mihai Todor, the result is this class that currently works for me. If it helps someone:
因此,将这个与Mihai Todor的出色解决方案和解释合并,结果是目前对我有用的这个类。如果它帮助某人:
MultipartUtility2V.java
MultipartUtility2V.java
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
public class MultipartUtilityV2 {
private HttpURLConnection httpConn;
private DataOutputStream request;
private final String boundary = "*****";
private final String crlf = "\r\n";
private final String twoHyphens = "--";
/**
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
*
* @param requestURL
* @throws IOException
*/
public MultipartUtilityV2(String requestURL)
throws IOException {
// creates a unique boundary based on time stamp
URL url = new URL(requestURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestMethod("POST");
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("Cache-Control", "no-cache");
httpConn.setRequestProperty(
"Content-Type", "multipart/form-data;boundary=" + this.boundary);
request = new DataOutputStream(httpConn.getOutputStream());
}
/**
* Adds a form field to the request
*
* @param name field name
* @param value field value
*/
public void addFormField(String name, String value)throws IOException {
request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" + name + "\""+ this.crlf);
request.writeBytes("Content-Type: text/plain; charset=UTF-8" + this.crlf);
request.writeBytes(this.crlf);
request.writeBytes(value+ this.crlf);
request.flush();
}
/**
* Adds a upload file section to the request
*
* @param fieldName name attribute in <input type="file" name="..." />
* @param uploadFile a File to be uploaded
* @throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" +
fieldName + "\";filename=\"" +
fileName + "\"" + this.crlf);
request.writeBytes(this.crlf);
byte[] bytes = Files.readAllBytes(uploadFile.toPath());
request.write(bytes);
}
/**
* 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() throws IOException {
String response ="";
request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary +
this.twoHyphens + this.crlf);
request.flush();
request.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
InputStream responseStream = new
BufferedInputStream(httpConn.getInputStream());
BufferedReader responseStreamReader =
new BufferedReader(new InputStreamReader(responseStream));
String line = "";
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
responseStreamReader.close();
response = stringBuilder.toString();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
回答by Nick C
This answer https://stackoverflow.com/a/33149413/6481542got me 90% of the way with uploading large files to a development Django server, but I had to use setFixedLengthStreamingModeto make it worked. That requires setting the Content-Length before writing the content, thus requiring a fairly significant rewrite of the above answer. Here's my end result
这个答案https://stackoverflow.com/a/33149413/6481542让我将大文件上传到开发 Django 服务器的方式达到了 90%,但我不得不使用setFixedLengthStreamingMode使其工作。这需要在编写内容之前设置 Content-Length,因此需要对上述答案进行相当大的重写。这是我的最终结果
public class MultipartLargeUtility {
private final String boundary;
private static final String LINE_FEED = "\r\n";
private HttpURLConnection httpConn;
private String charset;
private OutputStream outputStream;
private PrintWriter writer;
private final int maxBufferSize = 4096;
private long contentLength = 0;
private URL url;
private List<FormField> fields;
private List<FilePart> files;
private class FormField {
public String name;
public String value;
public FormField(String name, String value) {
this.name = name;
this.value = value;
}
}
private class FilePart {
public String fieldName;
public File uploadFile;
public FilePart(String fieldName, File uploadFile) {
this.fieldName = fieldName;
this.uploadFile = uploadFile;
}
}
/**
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
*
* @param requestURL
* @param charset
* @throws IOException
*/
public MultipartLargeUtility(String requestURL, String charset, boolean requireCSRF)
throws IOException {
this.charset = charset;
// creates a unique boundary based on time stamp
boundary = "===" + System.currentTimeMillis() + "===";
url = new URL(requestURL);
fields = new ArrayList<>();
files = new ArrayList<>();
if (requireCSRF) {
getCSRF();
}
}
/**
* Adds a form field to the request
*
* @param name field name
* @param value field value
*/
public void addFormField(String name, String value)
throws UnsupportedEncodingException {
String fieldContent = "--" + boundary + LINE_FEED;
fieldContent += "Content-Disposition: form-data; name=\"" + name + "\"" + LINE_FEED;
fieldContent += "Content-Type: text/plain; charset=" + charset + LINE_FEED;
fieldContent += LINE_FEED;
fieldContent += value + LINE_FEED;
contentLength += fieldContent.getBytes(charset).length;
fields.add(new FormField(name, value));
}
/**
* Adds a upload file section to the request
*
* @param fieldName name attribute in <input type="file" name="..." />
* @param uploadFile a File to be uploaded
* @throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
String fieldContent = "--" + boundary + LINE_FEED;
fieldContent += "Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"" + LINE_FEED;
fieldContent += "Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName) + LINE_FEED;
fieldContent += "Content-Transfer-Encoding: binary" + LINE_FEED;
fieldContent += LINE_FEED;
// file content would go here
fieldContent += LINE_FEED;
contentLength += fieldContent.getBytes(charset).length;
contentLength += uploadFile.length();
files.add(new FilePart(fieldName, uploadFile));
}
/**
* Adds a header field to the request.
*
* @param name - name of the header field
* @param value - value of the header field
*/
//public void addHeaderField(String name, String value) {
// writer.append(name + ": " + value).append(LINE_FEED);
// writer.flush();
//}
/**
* 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 List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
String content = "--" + boundary + "--" + LINE_FEED;
contentLength += content.getBytes(charset).length;
if (!openConnection()) {
return response;
}
writeContent();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
private boolean getCSRF()
throws IOException {
/// First, need to get CSRF token from server
/// Use GET request to get the token
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false); // Don't use a Cached Copy
conn.setRequestMethod("GET");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.getContent();
conn.disconnect();
/// parse the returned object for the CSRF token
CookieStore cookieJar = cookieManager.getCookieStore();
List<HttpCookie> cookies = cookieJar.getCookies();
String csrf = null;
for (HttpCookie cookie : cookies) {
Log.d("cookie", "" + cookie);
if (cookie.getName().equals("csrftoken")) {
csrf = cookie.getValue();
break;
}
}
if (csrf == null) {
Log.d(TAG, "Unable to get CSRF");
return false;
}
Log.d(TAG, "Received cookie: " + csrf);
addFormField("csrfmiddlewaretoken", csrf);
return true;
}
private boolean openConnection()
throws IOException {
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
//httpConn.setRequestProperty("Accept-Encoding", "identity");
httpConn.setFixedLengthStreamingMode(contentLength);
httpConn.setRequestProperty("Connection", "Keep-Alive");
httpConn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
outputStream = new BufferedOutputStream(httpConn.getOutputStream());
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
return true;
}
private void writeContent()
throws IOException {
for (FormField field : fields) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + field.name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(field.value).append(LINE_FEED);
writer.flush();
}
for (FilePart filePart : files) {
String fileName = filePart.uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + filePart.fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(filePart.uploadFile);
int bufferSize = Math.min(inputStream.available(), maxBufferSize);
byte[] buffer = new byte[bufferSize];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer, 0, bufferSize)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
writer.append(LINE_FEED);
writer.flush();
}
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
}
}
Usage is largely the same as in the above answer, but I've included CSRF support that Django uses by default with forms
用法与上面的答案大致相同,但我已经包含了 Django 默认使用表单的 CSRF 支持
boolean useCSRF = true;
MultipartLargeUtility multipart = new MultipartLargeUtility(url, "UTF-8",useCSRF);
multipart.addFormField("param1","value");
multipart.addFilePart("filefield",new File("/path/to/file"));
List<String> response = multipart.finish();
Log.w(TAG,"SERVER REPLIED:");
for(String line : response) {
Log.w(TAG, "Upload Files Response:::" + line);
}
回答by m_____ilk
based on Mihai's solution, if anyone has the problem of saving images on the server like what happened on my server. change the Bitmap to bytebuffer part to :
基于 Mihai 的解决方案,如果有人有像我的服务器上发生的那样在服务器上保存图像的问题。将 Bitmap to bytebuffer 部分更改为:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,100,bos);
byte[] pixels = bos.toByteArray();
回答by Rico Yao
I haven't tested this, but you might try using PipedInputStream and PipedOutputStream. It might look something like:
我还没有测试过这个,但你可以尝试使用 PipedInputStream 和 PipedOutputStream。它可能看起来像:
final Bitmap bmp = … // your bitmap
// Set up Piped streams
final PipedOutputStream pos = new PipedOutputStream(new ByteArrayOutputStream());
final PipedInputStream pis = new PipedInputStream(pos);
// Send bitmap data to the PipedOutputStream in a separate thread
new Thread() {
public void run() {
bmp.compress(Bitmap.CompressFormat.PNG, 100, pos);
}
}.start();
// Send POST request
try {
// Construct InputStreamEntity that feeds off of the PipedInputStream
InputStreamEntity reqEntity = new InputStreamEntity(pis, -1);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
reqEntity.setContentType("binary/octet-stream");
reqEntity.setChunked(true);
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
} catch (Exception e) {
e.printStackTrace()
}
回答by Sheraz Ahmad Khilji
Here is what i did for uploading photo using post request.
这是我使用发布请求上传照片所做的工作。
public void uploadFile(int directoryID, String filePath) {
Bitmap bitmapOrg = BitmapFactory.decodeFile(filePath);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
String upload_url = BASE_URL + UPLOAD_FILE;
bitmapOrg.compress(Bitmap.CompressFormat.JPEG, 90, bao);
byte[] data = bao.toByteArray();
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(upload_url);
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
try {
// Set Data and Content-type header for the image
FileBody fb = new FileBody(new File(filePath), "image/jpeg");
StringBody contentString = new StringBody(directoryID + "");
entity.addPart("file", fb);
entity.addPart("directory_id", contentString);
postRequest.setEntity(entity);
HttpResponse response = httpClient.execute(postRequest);
// Read the response
String jsonString = EntityUtils.toString(response.getEntity());
Log.e("response after uploading file ", jsonString);
} catch (Exception e) {
Log.e("Error in uploadFile", e.getMessage());
}
}
NOTE:This code requires libraries so Follow the instructions herein order to get the libraries.
注意:此代码需要库,因此请按照此处的说明获取库。
回答by Clive Jefferies
I found using okHttp a lot easier as I could not get any of these solutions to work: https://stackoverflow.com/a/37942387/447549
我发现使用 okHttp 更容易,因为我无法让这些解决方案中的任何一个工作:https://stackoverflow.com/a/37942387/447549
回答by Viktor Nikitenko
I tried the solutions above and none worked for me out of the box.
我尝试了上面的解决方案,但没有一个开箱即用。
However http://www.baeldung.com/httpclient-post-http-request. Line 6 POST Multipart Request worked within seconds
但是http://www.baeldung.com/httpclient-post-http-request。第 6 行 POST Multipart Request 在几秒钟内工作
public void whenSendMultipartRequestUsingHttpClient_thenCorrect()
throws ClientProtocolException, IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://www.example.com");
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("username", "John");
builder.addTextBody("password", "pass");
builder.addBinaryBody("file", new File("test.txt"),
ContentType.APPLICATION_OCTET_STREAM, "file.ext");
HttpEntity multipart = builder.build();
httpPost.setEntity(multipart);
CloseableHttpResponse response = client.execute(httpPost);
client.close();
}