多部分表单数据中文件名中的国际字符

时间:2010-08-03 03:44:00

标签: java http internationalization

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

如果我在那里使用标准API,则服务器返回HTTP状态Forbidden。如果我修改上传代码,那么文件名是urlencoded:

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

3 个答案:

答案 0 :(得分:4)

要专门针对Dropbox服务器解决此问题,我必须在utf8中对文件名进行编码。为此,我必须按如下方式声明我的多部分实体:

MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null, Charset.forName(HTTP.UTF_8));

由于OAuth签名的实体与发送的实际实体不匹配(正在​​进行URL编码),我得到了禁止。

对于那些对标准有什么兴趣的人,我做了一些RFC的阅读。 如果严格遵守标准,则所有标题应编码为7位,这将使文件名的utf8编码非法。但RFC2388()声明:

  

原始本地文件名可能是   也作为一个提供   “filename”参数中的任何一个   “content-disposition:form-data”   标题或,在多个的情况下   文件,在“内容处理:   文件“子部分的标题   发送应用程序可以提供文件   名称;如果是发件人的文件名   操作系统不是US-ASCII,   文件名可能是近似的,   或使用RFC的方法编码   2231。

很多帖子都提到使用rfc2231或rfc2047来编码7位非US-ASCII的标头。但是rfc2047在第5.3节中明确说明了编码的单词不能在Content-Disposition字段上使用。这只会留下rfc2231,但这是一个扩展,不能依赖于在所有服务器中实现。实际情况是,大多数主流浏览器都在UTF-8中发送非US-ASCII字符(因此Apache HTTP客户端中的HttpMultipartMode.BROWSER_COMPATIBLE模式),因此大多数Web服务器都会支持这一点。另外需要注意的是,如果在多部分实体上使用HttpMultipartMode.STRICT,该库实际上会将非ASCII替换为filename.S中的问号(?)。

答案 1 :(得分:2)

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

答案 2 :(得分:0)

快速修复:

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