java - Android:上传文件和填写POST正文一起

标签 java php android file-upload multipartentity

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

中正确显示

但我还需要填写 POST 主体以通过 php://stdin

读取

我该怎么做?

当前 fragment 如下:

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 的一部分,documentation

与此类似:Android: Uploading a file to a page along with other POST strings

最佳答案

随便加几个FormBodyPart到你的MultipartEntity .

您可以使用 StringBody对象提供值。

这是一个如何使用它的例子:

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 脚本的输出:

$_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
)

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

您无法访问来自 php://stdin 的数据或 $HTTP_RAW_POST_DATA ,两者都不可用于多部分/表单数据编码。来自 PHP 文档:

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 to On 它仍然不能解决问题:

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

这里是 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"

编辑:再三考虑后,我认为最好只使用一个 StringBody并将所有数据放在一个 post 变量中,然后从中解析它,它跳过将数据写入文件并在请求后删除它,因为临时文件完全无用,这将提高性能。 这是一个例子:

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

关于java - Android:上传文件和填写POST正文一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8965022/

相关文章:

java.sql.SQLException : ORA-01861: literal does not match format string

java - 在 jTextArea 中打印 jRadioButtons

php - fgetcsv/fputcsv $escape 参数从根本上被破坏

PHP、MySQL : Select inside a while Loop?

php - 我的 php while 循环没有解析整个表

java - JSSC 在 Arduino 中不闪烁 LED 灯

java - 更新 java.sql.Timestamp

javascript - 如何在phonegap的按钮上添加功能?

android - 解析时出现 Empty TextField 错误。不能应用 bool 条件

android - 当最小化Android应用程序标题栏颜色变化时