问题 如何在Android上使用multipart / form-data上传图片/图片


这是我的代码。

我得到了Http 400错误,有人能帮帮我吗?

HttpClient   httpClient;
HttpPost     httpPost;
HttpResponse response;
HttpContext  localContext;
FileEntity   tmp = null;   
String       ret = null;

httpClient = new DefaultHttpClient( );
httpClient.getParams().setParameter( ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109) ;

httpPost = new HttpPost(url);
tmp      = new FileEntity( data,"UTF-8" );

httpPost.setEntity( tmp );
httpPost.setHeader( "Content-Type", "multipart/form-data" );
httpPost.setHeader( "access_token", facebook.getAccessToken( ) );
httpPost.setHeader( "source",       data.getAbsolutePath( ) );
httpPost.setHeader( "message",      "Caption for the photo" );

localContext = new BasicHttpContext( );
response     = httpClient.execute( httpPost,localContext );

bobince,谢谢这是我的新ID,我会尝试将OAuth放到我的连接头。

这是我的旧代码,我会尽快更新。

private void uploadPicture( ) throws ParseException, IOException {
    HttpClient httpclient = new DefaultHttpClient();
    httpclient.getParams( ).setParameter( CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1 );

    HttpPost httppost = new HttpPost( "https://graph.facebook.com/me/photos" );
    File file = new File( sdpicturePath );

    // DEBUG
    Log.d( "TSET", "FILE::" + file.exists( ) ); // IT IS NOT NULL
    Log.d( "TEST", "AT:" + fbAccessToken ); // I GOT SOME ACCESS TOKEN

    MultipartEntity mpEntity  = new MultipartEntity( );
    ContentBody cbFile        = new FileBody( file, "image/png" );
    ContentBody cbMessage     = new StringBody( "TEST TSET" );
    ContentBody cbAccessToken = new StringBody( fbAccessToken );

    mpEntity.addPart( "access_token", cbAccessToken );
    mpEntity.addPart( "source",       cbFile        );
    mpEntity.addPart( "message",      cbMessage     );        

    httppost.setEntity( mpEntity );

    // DEBUG
    System.out.println( "executing request " + httppost.getRequestLine( ) );
    HttpResponse response = httpclient.execute( httppost );
    HttpEntity resEntity = response.getEntity( );

    // DEBUG
    System.out.println( response.getStatusLine( ) );
    if (resEntity != null) {
      System.out.println( EntityUtils.toString( resEntity ) );
    } // end if

    if (resEntity != null) {
      resEntity.consumeContent( );
    } // end if

    httpclient.getConnectionManager( ).shutdown( );
} // end of uploadPicture( )

11671
2017-07-29 09:17


起源

有些身体帮助我...... - Joseph
嗨,你是怎么解决这个问题的?我现在面临同样的问题。 - Zhenxiao Hao


答案:


setEntity 设置整个请求体的来源,所以这只有在 data 文件已经编码 multipart/form-data 块。

创建一个 multipart/form-data-encoded表单提交用作POST请求主体,通常需要MIME多部分编码器 org.apache.http.entity.mime.MultipartEntity。不幸的是,这不是由Android捆绑的,所以如果你想要它,你将不得不拉入更新的 HttpClient的 来自Apache。

看到 这个问题 例如代码和 这个帖子 为背景。


8
2017-07-29 10:33



非常感谢,我现在正在尝试。 ^ ___ ^ - Joseph
凉!!但是现在我得到了错误... >> {“error”:{“type”:“OAuthException”,“message”:“无效的OAuth访问令牌。”}} - Joseph
OAuth是一个应用程序级问题,与文件上载或表单创建无关。听起来你需要通过 oauth_ 头 请求授权访问用户数据。 - bobince
我在facebook应用程序信息页面上对OAuth进行了罚款。非常感谢。 - Joseph
我正在尝试在Facebook上传视频..我希望你可以帮助我使用多部分请求上传视频.. - Jaffar Raza


有我的工作解决方案使用apache http库发送带有post的图像:

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] imageBytes = baos.toByteArray();

            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(StaticData.AMBAJE_SERVER_URL + StaticData.AMBAJE_ADD_AMBAJ_TO_GROUP);

            String boundary = "-------------" + System.currentTimeMillis();

            httpPost.setHeader("Content-type", "multipart/form-data; boundary="+boundary);

            ByteArrayBody bab = new ByteArrayBody(imageBytes, "pic.png");
            StringBody sbOwner = new StringBody(StaticData.loggedUserId, ContentType.TEXT_PLAIN);
            StringBody sbGroup = new StringBody("group", ContentType.TEXT_PLAIN);

            HttpEntity entity = MultipartEntityBuilder.create()
                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                    .setBoundary(boundary)
                    .addPart("group", sbGroup)
                    .addPart("owner", sbOwner)
                    .addPart("image", bab)
                    .build();

            httpPost.setEntity(entity);

            try {
                HttpResponse response = httpclient.execute(httpPost);
                ...then reading response

3
2017-08-14 12:27





至于facebook graph api,这段代码非常完美。 但是,有时候,你需要使用 名称 代替 文件名,图api似乎与rfc文件冲突。

final String BOUNDERY = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
final String CRLF = "\r\n";
StringBuilder sbBody_1 = new StringBuilder();
sbBody_1.append("--" + BOUNDERY + CRLF);
sbBody_1.append("Content-Disposition: form-data; filename=\"source\"" + CRLF);
sbBody_1.append(CRLF);
StringBuilder sbBody_2 = new StringBuilder();
sbBody_2.append(CRLF + "--" + BOUNDERY + "--");
URL url = new URL("https://graph.facebook.com/me/photos?access_token=" + accessToken);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDERY);
connection.setChunkedStreamingMode(0);
OutputStream out = new BufferedOutputStream(connection.getOutputStream());
out.write(sbBody_1.toString().getBytes());
out.write(bFile);// bFile is byte array of the bitmap
out.write(sbBody_2.toString().getBytes());
out.close();
BufferedReader bips = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String temp = null;
while ((temp = bips.readLine()) != null) {
    Log.d("fbnb", temp);
}
bips.close();
connection.disconnect();

1
2018-03-09 15:52