Java Multipart formdata文件名中的国际字符

Java Multipart formdata文件名中的国际字符,java,http,internationalization,Java,Http,Internationalization,我正在使用ApacheHTTP组件(4.1-alpha2)将文件上载到dropbox。这是使用多部分表单数据完成的。以包含国际(非ascii)字符的多部分形式对文件名进行编码的正确方法是什么 如果我使用标准API,服务器将返回HTTP禁止状态。如果我修改上载代码,使文件名为URL编码: MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); FileBody bin = new Fil

我正在使用ApacheHTTP组件(4.1-alpha2)将文件上载到dropbox。这是使用多部分表单数据完成的。以包含国际(非ascii)字符的多部分形式对文件名进行编码的正确方法是什么

如果我使用标准API,服务器将返回HTTP禁止状态。如果我修改上载代码,使文件名为URL编码:

MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody bin = new FileBody(file_obj, URLEncoder.encode(file_obj.getName(), HTTP.UTF_8), HTTP.UTF_8, HTTP.OCTET_STREAM_TYPE );
entity.addPart("file", bin);            
req.setEntity(entity);

该文件已上载,但最终文件名仍被编码。例如,%D1%82%D0%B5%D1%81%D1%82.txt

我本以为
文件体的实现将负责从自身应用适当的规则。然后文件名将被编码为
=?UTF-8?Q?=D1=82=D0=B5=D1=81=D1=82.txt?=
或类似的东西。

为了解决这个问题,我必须用utf8编码文件名。为此,我必须声明我的多部分实体,如下所示:

MultipartEntity=new MultipartEntity(HttpMultipartMode.BROWSER_兼容,null,Charset.forName(HTTP.UTF_8))

因为OAuth签名的实体与实际发送的实体不匹配(它是URL编码的),所以我得到了禁止

对于那些对这些标准有兴趣的人,我读了一些RFC。 如果严格遵守该标准,则所有标题都应编码为7bit,这将使文件名的utf8编码非法。然而,RFC2388()指出:

原始本地文件名可能是 也提供,作为 “filename”参数 “内容处置:表单数据” 标题或,在多个标题的情况下 “内容处置”中的文件: 子部分的“文件”标题。这个 发送应用程序可能会提供一个文件 名称如果发件人的 操作系统不是US-ASCII, 文件名可能是近似值, 或使用RFC方法进行编码 2231

许多帖子提到在7bit中使用rfc2231或rfc2047对非US-ASCII的报头进行编码。但是,rfc2047在第5.3节中明确规定,不得在内容处置字段上使用编码字。这只会留下rfc2231,但这是一个扩展,不能依赖于在所有服务器中实现。事实上,大多数主流浏览器都以UTF-8格式发送非美国ASCII字符(因此在Apache HTTP客户端中采用了HttpMultipartMode.BROWSER\u兼容模式),因此,大多数web服务器都将支持这种方式。另一件需要注意的事情是,如果在多部分实体上使用HttpMultipartMode.STRICT,库实际上将用非ASCII替换文件名.S中的问号(?)

快速修复:

new String(multipartFile.getOriginalFilename().getBytes ("iso-8859-1"), "UTF-8");

谢谢罗兰。我仔细查看了httpime代码,甚至发现了这个bug:。当我从commmons codec使用QCodec手动编码时,我得到的结果与使用URLCoder类似。我认为dropbox服务器可能没有正确处理这个问题。