2011-01-19 77 views
6

我该如何在java.Currently中设置本地化文件名每次我点击一个本地化文件,在我的应用程序中有一个非ASCII文件名,窗口保存对话框弹出,但它没有正确显示文件名,如果字符集是高于ISO-88859-1的任何字符。Java本地化文件名

这是我保存文件的代码。

  InputStream inputStream = null; 
try { 
    response.resetBuffer(); 
    response.setContentType(fileStream.getContentType()); 
    response.setContentLength((int) fileStream.getContentLength()); 
    response.addHeader("Content-Disposition", 
    "attachment;filename=\"" + fileName + "\""); 
    ServletOutputStream stream = response.getOutputStream(); 
    byte[] buffer = new byte[1024]; 
    int read = 0; 
    int total = 0; 
    inputStream = fileStream.getInputStream(); 
    while ((read = inputStream.read(buffer)) > 0) { 
    stream.write(buffer, 0, read); 
    total += read; 
    } 
    response.flushBuffer(); 
} finally { 
    if (inputStream != null) { 
    inputStream.close(); 
    } 
} 

如果有人能就如何解决此问题分享他们的想法,我会非常有帮助。 在此先感谢。

回答

13

gustafc说的是正确的,但它并没有让你到达你想要的位置。 RFC 2231允许您使用非ASCII Content-TypeContent-Disposition参数的替代格式,但并非所有浏览器都支持它。这是最有可能在上班的路上,不幸的是,忽略什么RFC 2183说,并在回应中使用RFC 2047 encoded-words

response.addHeader("Content-Disposition", "attachment; " + 
    "filename=\"" + MimeUtility.encodeWord(fileName, "utf-8", "Q") + "\""); 

注意,这可能不适用于所有浏览器。 IE的一些变型要求URL编码,而不是值:用检测组合

response.addHeader("Content-Disposition", 
    "attachment; filename=" + URLEncoder.encode(filename, "utf-8")); 
2

section 2.3 in the spec,看来你不能使用非US-ASCII字符:

当前[RFC 2045]语法限制参数值(并因此 内容配置文件名),以US-ASCII。我们认识到允许在文件名中使用任意字符集的好处 ,但是 定义必要的 机制超出了本文档的范围。我们预计基本的[RFC 1521]“值” 规范将在某一天被修改为允许使用非US-ASCII 字符,此时应在 Content-Disposition文件名参数中使用相同的机制。

+0

这是准确的,但无济于事。 :) – dkarp 2011-01-19 16:43:43

+0

Gustafc,感谢您的时间和RFC的指出这些不良结果的原因。 – Hitatichi 2011-01-20 07:19:35

4

我面临类似的问题与含有希腊语characters.I文件名中使用的(我的感谢dkarp)上面的回答所提供的代码浏览器被使用。这是结果:

 
String user_agent = request.getHeader("user-agent"); 
boolean isInternetExplorer = (user_agent.indexOf("MSIE") > -1); 
if (isInternetExplorer) { 
    response.setHeader("Content-disposition", "attachment; filename=\"" + URLEncoder.encode(filename, "utf-8") + "\""); 
} else { 
    response.setHeader("Content-disposition", "attachment; filename=\"" + MimeUtility.encodeWord(filename) + "\""); 
} 

我测试了它与Firefox 3.6,铬10.0和Internet Explorer 8,它似乎工作正常。

1

虽然这是个老问题,但它仍然是实际的。我发现适用于所有浏览器的解决方案。

见我在其他主题发表:
Java servlet download filename special characters

总之,浏览器预计filename参数值在浏览器中编码本地编码(如果filename参数没有指定字符集不同)。浏览器的本地编码通常是utf-8(FF,Opera,Chrome),但对于IE而言,它是win-1250。因此,如果我们将价值放入filename参数中,那么根据用户的浏览器将其编码为utf-8/win-1250,它应该可以工作。

例如,如果我们有文件名为omáčka.xml
对于Firefox,Opera和铬I反应此标头(编码UTF-8):

Content-Disposition: attachment; filename="omáčka.xml" 

和用于IE I反应此标头(编码在Win-1250):

Content-Disposition: attachment; filename="omáèka.jpg" 

Java示例是上述in my post

注#1(@dkarp)

注意使用URLEncoder.encode(),因为这种方法不编码输入字符串为网址编码的。此方法将输入字符串编码为非常类似的表单编码,但在某些情况下会有所不同 - 例如空格字符''编码为'+'而不是'%20'。

进行正确的URL编码,你应该宁愿使用URI类:

URI uri = new URI(null, null, "foo-ä-€.html", null); 
System.out.println(uri.toASCIIString());