通过MultipartEntity发送Unicode字符

3

我有一种方法,可以使用MultipartEntity内容类型发送图像和文本作为HttpPost。对于英文符号,一切都很好,但是对于Unicode符号(例如Cyrliics),它只发送???。因此,我想知道如何正确设置MultipartEntity的UTF-8编码,因为我已经尝试了SO上提出的几种解决方案,但没有一种可行。

这是我已经尝试过的:

HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);

MultipartEntityBuilder mpEntity = MultipartEntityBuilder.create();
mpEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mpEntity.setCharset(Consts.UTF_8);

mpEntity.addPart("image", new FileBody(new File(attachmentUri), ContentType.APPLICATION_OCTET_STREAM));


ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
StringBody stringBody = new StringBody(mMessage, contentType);
mpEntity.addPart("message", stringBody);

final HttpEntity fileBody = mpEntity.build();
httpPost.setEntity(fileBody);  

HttpResponse httpResponse = httpclient.execute(httpPost);

更新 我尝试按照@Donaudampfschifffreizeitfahrt的建议使用InputStream。现在我得到了���字符。

 InputStream stream = new ByteArrayInputStream(mMessage.getBytes(Charset.forName("UTF-8")));
 mpEntity.addBinaryBody("message", stream);

我也尝试过以下方法:

mpEntity.addBinaryBody("message", mMessage.getBytes(Charset.forName("UTF-8")));

1
你正在使用“默认字符集”进行IO操作,无论你使用的是什么。这是Sun的一个可怕设计,如果你要处理写入/读取字符串,你必须始终使用指定编码的OutputStreamReader/InputStreamWriter。 - Danubian Sailor
@Donaudampfschifffreizeitfahrt 你好!请问您能否更具体地说明一下,在我的问题上如何使用InputStreamWriter?最好能提供一个示例。谢谢。 - mol
哦,应该是OutputStreamWriter和InputStreamReader。httpclient必须接受Writer类型的Body,但我现在没有这个库。只需搜索这些类名即可。 - Danubian Sailor
@Donaudampfschifffreizeitfahrt 谢谢您的解释,但似乎并没有帮助到我,请查看我的更新问题,并纠正我是否误解了您的建议。 - mol
3个回答

9
我用不同的方法解决了这个问题,使用以下内容:
builder.addTextBody(key, שלום, ContentType.TEXT_PLAIN.withCharset("UTF-8"));

2
您可以使用以下代码将部分添加到多部分实体中:

entity.addPart("Data", new StringBody(data,Charset.forName("UTF-8")));

从而在请求中发送Unicode编码的数据。

0
对于那些遇到这个问题的人,这是我解决它的方法:
我调查了Apache Http Components库的源代码,并发现以下内容:
org.apache.http.entity.mime.HttpMultipart::doWriteTo()


case BROWSER_COMPATIBLE:
    // Only write Content-Disposition
    // Use content charset

    final MinimalField cd = part.getHeader().getField(MIME.CONTENT_DISPOSITION);
    writeField(cd, this.charset, out);
    final String filename = part.getBody().getFilename();
    if (filename != null) {
        final MinimalField ct = part.getHeader().getField(MIME.CONTENT_TYPE);
        writeField(ct, this.charset, out);
    }
    break;

看起来是 Apache lib 中的某种错误/特性,只允许将 Content-type 头添加到 MultipartEntity 的一个具有非空文件名的部分。所以我修改了我的代码:

Charset utf8 = Charset.forName("utf-8");
ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), utf8);
ContentBody body = new ByteArrayBody(mMessage.getBytes(), contentType, "filename");
mpEntity.addPart("message", body);

对于字符串部分, Content-type 标头已出现,符号现在可以正确地编码和解码。


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