首页 文章

mutipart formdata中文件名中的国际字符

提问于
浏览
4

我正在使用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 回答

  • 2

    要专门针对Dropbox服务器解决此问题,我必须在utf8中对文件名进行编码 . 要做到这一点,我必须声明我的multipart实体如下:

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

    由于OAuth签名的实体与发送的实际实体(它是URL编码的)不匹配,我得到了禁止 .

    对于那些对标准有关的内容感兴趣的人,我做了一些RFC的阅读 . 如果严格遵守标准,则所有 Headers 应编码为7位,这将使文件名的utf8编码非法 . 但RFC2388()规定:

    也可以提供原始本地文件名,作为“content-disposition:form-data” Headers 的“filename”参数,或者在多个文件的情况下,在“content-disposition:file”中 . 子部分的 Headers . 发送应用程序可以提供文件名;如果发件人操作系统的文件名不是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中的问号(?) .

  • 4

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

  • 0

    快速解决:

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

相关问题