【问题标题】:International characters in filename in mutipart formdata多部分表单数据中文件名中的国际字符
【发布时间】:2010-08-03 03:43:59
【问题描述】:

我正在使用 Apache HTTP 组件 (4.1-alpha2) 将文件上传到保管箱。这是使用多部分表单数据完成的。以包含国际(非 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

【问题讨论】:

    标签: java http internationalization


    【解决方案1】:

    为了专门针对 Dropbox 服务器解决此问题,我必须将文件名编码为 utf8。为此,我必须如下声明我的多部分实体:

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

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

    对于那些对标准对此有何评论感兴趣的人,我阅读了一些 RFC。 如果严格遵守标准,则所有标头都应编码为 7 位,这将使文件名的 utf8 编码非法。然而 RFC2388 () 声明:

    原来的本地文件名可能是 提供以及,或者作为 “文件名”参数 “内容处置:表单数据” 标头,或者在多个的情况下 文件,在“内容处置: 文件”子部分的标题。 发送应用程序可以提供一个文件 姓名;如果发件人的文件名 操作系统不是 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 替换文件名中的问号 (?)。S

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢罗兰。我仔细查看了 httpmime 代码,甚至发现了这个错误:issues.apache.org/jira/browse/HTTPCLIENT-293。当我使用来自 commmons-codec 的 QCodec 手动编码时,我得到与使用 URLEncoder 类似的结果。我在想 Dropbox 服务器可能没有正确处理这个。
      【解决方案3】:

      快速修复:

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

      【讨论】:

        猜你喜欢
        • 2018-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        • 2017-09-21
        • 2020-07-18
        • 2016-09-24
        相关资源
        最近更新 更多