2

私は MultipartEntity を使用してファイルをサーバーに送信しますが、$_FILESスーパーグローバルに正しく表示されます

ただし、POST 本文を入力して読み取る必要もあります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、ドキュメントの一部です

これに似ています: Android: 他の POST 文字列と一緒にページにファイルをアップロードする

4

1 に答える 1

21

にいくつか追加するだけ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
)

これは、1 つのコンテンツ ボディ パーツ内のすべての投稿変数を圧縮するわけではありませんが、ジョブを実行します。

php://stdinまたは$HTTP_RAW_POST_DATAからデータにアクセスすることはできません。どちらも multipart/form-data エンコーディングには使用できません。PHPドキュメントから:

php://input は、リクエスト本文から生データを読み取ることができる読み取り専用ストリームです。POST リクエストの場合、特別な php.ini ディレクティブに依存しないため、$HTTP_RAW_POST_DATA の代わりに php://input を使用することをお勧めします。さらに、$HTTP_RAW_POST_DATA がデフォルトで設定されていない場合は、always_populate_raw_post_data をアクティブ化する代わりに、メモリ消費量が少ない可能性があります。php://input は enctype="multipart/form-data" では使用できません。

On に設定always_populate_raw_post_dataしても、問題は解決しません。

生の POST データを含む $HTTP_RAW_POST_DATA を常に設定します。それ以外の場合、認識されない MIME タイプのデータのみが変数に取り込まれます。ただし、生の POST データにアクセスするための推奨される方法は php://input です。enctype="multipart/form-data" では $HTTP_RAW_POST_DATA を使用できません。

ByteArrayBody私の最善の推測は、すべてのデータをorとして追加し、それStringBodyを 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=送信"

StringBody編集:いくつか考え直した後、1つを使用してすべてのデータを1つの投稿変数に入れてから解析する方が良いと思います。一時ファイルは完全に役に立たないので、パフォーマンスが向上します。次に例を示します。

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']);
于 2012-01-25T13:42:34.297 に答える