Android多部分HTTP Post没有发送文件的MIME类型

11

我正在尝试弄清楚我的代码出了什么问题。我遵循了来自这里的博客文章。

我设法让代码将文件实际上传到PHP Web服务。但是,由于某种原因,尽管我已显式设置了文件的MIME类型,但PHP显示MIME只是一个空字符串,因此被拒绝。

这是我的代码:

public String SendPost(String fn, String bid, String caption, String uid, String APIKey, String postHash) 
        throws ParseException, ClientProtocolException, IOException {
    HttpClient httpclient = new DefaultHttpClient();
    httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

    HttpPost httppost = new HttpPost(UrbURL);

    Log.i("POSTFN", fn);
    Log.i("POSTFN", bid);
    Log.i("POSTFN", caption);
    Log.i("POSTFN", uid);
    Log.i("POSTFN", APIKey);
    Log.i("POSTFN", postHash);

    String postAuth = uid + postHash;
    postAuth = md5(postAuth);
    postAuth = postAuth.substring(0, 16);
    //Log.i("POSTAUTH", postAuth);

    MultipartEntity mp = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

    /*File tempImg = new File(fn);
    FileBody bin = new FileBody(tempImg, "image/jpg");*/
    mp.addPart("business_photo", new FileBody(new File(fn), "image/jpg"));

    //StringBody s = new StringBody(bid, "text/plain", Charset.forName( "UTF-8" ));
    mp.addPart("business_id", new StringBody(bid, "text/plain", Charset.forName( "UTF-8" )));

    //s = new StringBody(caption, "text/plain", Charset.forName( "UTF-8" ));
    mp.addPart("photo_caption", new StringBody(caption, "text/plain", Charset.forName( "UTF-8" )));

    //s = new StringBody(uid, "text/plain", Charset.forName( "UTF-8" ));
    mp.addPart("user_id", new StringBody(uid, "text/plain", Charset.forName( "UTF-8" )));

    //s = new StringBody(APIKey, "text/plain", Charset.forName( "UTF-8" ));
    mp.addPart("apikey", new StringBody(APIKey, "text/plain", Charset.forName( "UTF-8" )));

    //s = new StringBody(postAuth, "text/plain", Charset.forName( "UTF-8" ));
    mp.addPart("auth", new StringBody(postAuth, "text/plain", Charset.forName( "UTF-8" )));

    httppost.setEntity(mp);

    String response = EntityUtils.toString( httpclient.execute( httppost ).getEntity(), "UTF-8" );

    httpclient.getConnectionManager().shutdown();

    return response;
}

非常感谢您之前的帮助 :)


你好,能否告诉我什么是“字符集(charset)”,以及我应该设置什么? - SAndroidD
6个回答

5

我曾经遇到同样的问题,现在已经解决了。

我发现使用HttpMultipartMode.BROWSER_COMPATIBLE会阻止正确的mimeType在使用ByteArrayBody上传图片时被设置。我猜测你遇到的问题可能也是这个原因。

当我修改了这一行代码:

MultipartEntity mp = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

为了

MultipartEntity mp = new MultipartEntity();

然后正确设置了MIME类型,服务上传成功。

我发现人们使用BROWSER_COMPATIBLE来解决另一个问题,但希望您不需要这样做。


2

当我将HttpClient从版本4.1更新到版本4.4时,遇到了同样的问题。无论是删除HttpMultipartMode.BROWSER_COMPATIBLE还是替换为其他可选项都没有帮助。

对我来说需要最小更改的解决方案是在构建FileBody时明确指定filename,即替换原先的代码。

new FileBody(file, mimeType)

使用

new FileBody(file, filename, mimeType, charset)

关于 HttpClient 4.4 版本,可能的原因是 new FileBody(file, mimeType)null 分配给 filename 字段而不是使用 file.getName()。然后,在执行 HttpMultipart 中的 formatMultipartHeader 时,将要格式化的部分的 filenameBROWSER_COMPATIBLE 模式下检查是否为非空值。如果为空,则整个正文将被忽略。

1

虽然以上所有答案都有助于正确解决问题。

但仅仅删除HttpMultipartMode.BROWSER_COMPATIBLE是不够的。

您可以通过以下方式设置MIME类型

ByteArrayBody bab = new ByteArrayBody(params.getByteArray("data"), "image/jpeg" , "image.jpg");

注意:我正在使用最新的重新打包的Android客户端http://code.google.com/p/httpclientandroidlib/,它支持多部分上传等功能。


1

我们这里也有同样的问题。使用HttpMultipartMode.BROWSER_COMPATIBLE会导致正确的mimetype被删除。

不幸的是,对于我们来说,使用“正常”的MultipartEntity()不是一个选项,因为这种方式会使rails后端处理请求出现问题。

有没有办法设置multipart的content-type并使用HttpMultipartMode.BROWSER_COMPATIBLE


1
我曾经遇到过一个问题,就是当我尝试发送3个FileBody和1个mime信息时,除非我只发送一个filebody,否则mime(以json格式)永远不会被接收。我一直先添加了filebody,这导致了我的问题。后来我改变了顺序,先添加mime,然后每个信息包括mime都能在php服务器端正确地接收到。

1

你可以使用在Android中定义为内部类的http多部分类,而不是包含JAR文件,因此无法直接使用它们,你必须从android源代码下载并添加到你的项目中。在使用它们之前必须进行一些基本修改,这并不困难(更改包名称,删除所有记录器调用)。对我来说它运行得很完美。我希望这能帮助到某些人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接