1

我有一个使用 tomcat 提供的 Web 应用程序。

在其中一个页面上,它允许用户下载存储在我的文件服务器上的文件。那里存在的大多数文件的名称都是日文的。但是,当用户下载文件时,文件名是乱码。此外,它在不同的浏览器上的工作方式也不同。

原代码如下:

FileInputStream in = new FileInputStream(absolutePath);
ResponseUtil.download(new String(downloadFileName.getBytes("Shift_JIS"), "ISO-8859-1"), in);

例如,08_タイヨーアクリス_装置开発_実成绩表在 Google Chrome 中被解释为
08_ƒ^ƒCƒ^-[ƒAƒNƒŠƒX_'•'uŠJ”-_ŽÀ-Ñ• 在 Google Chrome 中
这个问题是由于文件名中存在“5c”和似乎是 Shift_JIS 中的一个已知问题。我想知道解决这个问题的正确方法。

4

2 回答 2

1

看起来ResponseUtil.download您正在使用的“Seasar sastruts”框架中的方法正在获取您提供的文件名并将其直接粘贴在Content-disposition它构造的 HTTP 响应的标头中。

response.setHeader("Content-disposition", "attachment; filename=" + fileName + "\"");

据我所知,HTTP 和 MIME 标头仅支持 ASCII 字符,因此该技术不适用于非 ASCII 字符。(如果是这种情况,我会认为它是此类中的一个错误,它会无条件地将文件名粘贴到标题中。)在传递字符串之前修改或尝试重新编码将不起作用,因为这编码处于不同的级别。

要支持非 ASCII 字符,需要使用MIME 编码字技术对标头值进行编码。没有办法按原样使用ResponseUtil该类,因为它将您直接提供的名称连接到非编码字字符串。

我认为您需要重写该download()方法以检查它接收的文件名输入中的非 ASCII 字符,并对包含它们的字符串使用编码字编码。您希望它看起来像这样,some_base64_text文件名字节的实际 base-64 编码在哪里编码为 Shift-JIS。(或者改用 UTF-8。)

Content-disposition: =?Shift_JIS?B?some_base64_text?=

围绕这个可能有很多不同的浏览器行为,因为他们试图绕过各种“错误”的网络服务器。但看起来以这种方式对其进行编码是让它工作并使其可移植的一个不错的选择。

于 2015-04-21T02:42:47.073 回答
1

非常感谢。我能够使用以下方法解决 Chrome 上的问题:

ResponseUtil.download(URLEncoder.encode(downloadFileName, "UTF-8"), in);

但是,Firefox 和 Safari 中的编码仍然不正确。

在 Chrome 中,文件名为“08_タイヨーアクリス_装置开発_実成绩表.pdf”,但在 Firefox 和 Safari 中,文件名为“08_%E3%82%BF%E3%82%A4%E3%83% A8%E3%83%BC%E3%82%A2%E3%82%AF%E3%83%AA%E3%82%B9_%E8%A3%85%E7%BD%AE%E9%96%8B% E7%99%BA_%E5%AE%9F%E7%B8%BE%E8%A1%A8.pdf”。

于 2015-04-21T06:15:09.007 回答