使用 POST 和 HttpURLConnection 发送文件 [英] Sending files using POST with HttpURLConnection

查看:37
本文介绍了使用 POST 和 HttpURLConnection 发送文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 Android 开发者建议使用HttpURLConnection 类,我想知道是否有人可以为我提供一个很好的示例,说明如何通过 POST 将位图文件"(实际上是内存中的流)发送到 Apache HTTP 服务器.我对 cookie 或身份验证或任何复杂的东西不感兴趣,但我只想有一个可靠的逻辑实现.我在这里看到的所有例子看起来更像是让我们试试这个,也许它会奏效".

Since the Android developers recommend to 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".

现在,我有这个代码:

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();
    }
}

showDialog 应该在哪里显示 AlertDialog(如果 URL 无效?).

where showDialog should just display an AlertDialog (in case of an invalid URL?).

现在,假设我生成了一个像这样的位图:Bitmap image = this.getBitmap() 在从 View 派生的控件中,我想通过邮政.实现这一目标的正确程序是什么?我需要使用哪些类?我可以像这个例子那样使用HttpPost吗?如果是这样,我将如何为我的位图构造 InputStreamEntity ?我会发现要求首先将位图存储在设备上的文件中是令人反感的.

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.

我还要提一下,我真的需要将原始位图的每个未更改像素发送到服务器,因此我无法将其转换为 JPEG.

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.

推荐答案

我不知道为什么 HttpURLConnection 类不提供任何发送文件的方法,而无需手动编写文件包装器.这是我最终做的,但如果有人知道更好的解决方案,请告诉我.

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.

输入数据:

Bitmap bitmap = myView.getBitmap();

静态内容:

String attachmentName = "bitmap";
String attachmentFileName = "bitmap.bmp";
String crlf = "
";
String twoHyphens = "--";
String boundary =  "*****";

设置请求:

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);

启动内容包装器:

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);

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);

结束内容包装器:

request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary + 
    this.twoHyphens + this.crlf);

刷新输出缓冲区:

request.flush();
request.close();

获取回复:

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("
");
}
responseStreamReader.close();

String response = stringBuilder.toString();

关闭响应流:

responseStream.close();

关闭连接:

httpUrlConnection.disconnect();

PS:当然我不得不把请求包裹在private class AsyncUploadBitmaps extends AsyncTask,为了让Android平台开心,因为它不喜欢在主线程上有网络请求.

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.

这篇关于使用 POST 和 HttpURLConnection 发送文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆