Android:上传文件并一起填写POST正文 [英] Android: upload file with filling out POST body together

查看:32
本文介绍了Android:上传文件并一起填写POST正文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确实使用 MultipartEntity 将文件发送到服务器,它在 $_FILES superglobal 中正确显示

I do use MultipartEntity to send File to server, it appears correctly in $_FILES superglobal

但我还需要填写 POST 正文以通过 php://stdin

But I need also fill in POST body to be read via php://stdin

我该怎么做?

下面的当前片段:

ByteArrayOutputStream bos = new ByteArrayOutputStream(); // stream to hold image
bm.compress(CompressFormat.JPEG, 75, bos); //compress image
byte[] data = bos.toByteArray(); 
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("REMOTE ADDRESS");
ByteArrayBody bab = new ByteArrayBody(data, "image.jpg");
MultipartEntity reqEntity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE); // is this one causing trouble?
reqEntity.addPart("image", bab); // added image to request
// tried this with no luck
// reqEntity.addPart("", new StringBody("RAW DATA HERE")); 
postRequest.setEntity(reqEntity); // set the multipart entity to http post request
HttpResponse response = httpClient.execute(postRequest);

MultipartEntity 是 HttpMime 4.1.2 API 的一部分,文档

MultipartEntity is part of HttpMime 4.1.2 API, documentation

类似于此:Android:将文件与其他 POST 字符串一起上传到页面

推荐答案

只需添加一些 FormBodyPart 到您的 MultipartEntity.

Just add a a few FormBodyPart to your MultipartEntity.

您可以使用 StringBody 对象来提供值.

You can use the StringBody object to provide the value.

以下是如何使用它的示例:

Here is an example of how you can use it:

byte[] data = {10,10,10,10,10}; 
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("server url");
ByteArrayBody bab = new ByteArrayBody(data, "image.jpg");
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("image", bab);

FormBodyPart bodyPart=new FormBodyPart("formVariableName", new StringBody("formValiableValue"));
reqEntity.addPart(bodyPart);
bodyPart=new FormBodyPart("formVariableName2", new StringBody("formValiableValue2"));
reqEntity.addPart(bodyPart);
bodyPart=new FormBodyPart("formVariableName3", new StringBody("formValiableValue3"));
reqEntity.addPart(bodyPart); 
postRequest.setEntity(reqEntity);
HttpResponse response = httpClient.execute(postRequest);
BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = null;
while((line = in.readLine()) != null) {
    System.out.println(line);
}

这是 PHP 脚本的输出:

Here is the output of the PHP script:

$_FILES
Array
(
    [image] => Array
        (
            [name] => image.jpg
            [type] => application/octet-stream
            [tmp_name] => /tmp/php6UHywL
            [error] => 0
            [size] => 5
        )

)
$_POST:
Array
(
    [formVariableName] => formValiableValue
    [formVariableName2] => formValiableValue2
    [formVariableName3] => formValiableValue3
)

这不会压缩一个内容正文部分内的所有帖子变量,但可以完成工作.

This doesn't compress all the post vars inside of one content body part but it dose the job.

您无法从 php://stdin$HTTP_RAW_POST_DATA,两者均不适用于 multipart/form-data 编码.来自 PHP 文档:

You can't access the data from php://stdin or $HTTP_RAW_POST_DATA, both are unavailable for multipart/form-data encoding. From the PHP docs:

php://input 是一个只读流,允许您读取原始数据来自请求正文.在 POST 请求的情况下,最好使用 php://input 而不是 $HTTP_RAW_POST_DATA 因为它没有依赖于特殊的 php.ini 指令.此外,对于那些情况$HTTP_RAW_POST_DATA 默认不填充,它是一个潜在的较少的内存密集型替代激活always_populate_raw_post_data.php://input 不可用enctype="multipart/form-data".

php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype="multipart/form-data".

即使你设置了always_populate_raw_post_data 到 On 它仍然不能解决问题:

Even if you set always_populate_raw_post_data to On it still won't fix the problem:

始终填充包含原始 POST 数据的 $HTTP_RAW_POST_DATA.否则,该变量仅填充无法识别的 MIME 类型的数据.但是,访问原始 POST 的首选方法数据是 php://input.$HTTP_RAW_POST_DATA 不可用于enctype="multipart/form-data".

Always populate the $HTTP_RAW_POST_DATA containing the raw POST data. Otherwise, the variable is populated only with unrecognized MIME type of the data. However, the preferred method for accessing the raw POST data is php://input. $HTTP_RAW_POST_DATA is not available with enctype="multipart/form-data".

我最好的猜测是将所有数据添加为 ByteArrayBodyStringBody 和只是使用它就像你正在阅读 php://stdin

My best guess is just add all the data as a ByteArrayBody or StringBody and just use that as if you were reading from php://stdin

这是一个的例子ByteArrayBody:

String testString="b=a&c=a&d=a&Send=Send";
reqEntity.addPart(new FormBodyPart("formVariables", new ByteArrayBody(testString.getBytes(), "application/x-www-form-urlencoded", "formVariables")));

在 PHP 中:

var_dump(file_get_contents($_FILES['formVariables']['tmp_name']));

你应该得到:

string(21) "b=a&c=a&d=a&Send=Send"

string(21) "b=a&c=a&d=a&Send=Send"

经过三思而后,我认为最好只使用一个 StringBody 并将所有数据放在一个 post 变量中,然后从中解析它,它跳过将数据写入文件并在请求,因为临时文件完全没用,这将提高性能.下面是一个例子:

After some second thoughts I think it's better to just use one StringBody and put all the data in one post variable, then parse it from that, it skips writing the data to a file and deleting it after the request since the temp file is totally useless this will increase performance. Here is an example:

String testString="b=a&c=a&d=a&Send=Send";
bodyPart=new FormBodyPart("rawData", new StringBody(testString));
reqEntity.addPart(bodyPart);

然后来自 PHP:

var_dump($_POST['rawData']);

这篇关于Android:上传文件并一起填写POST正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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