2011-01-19 5 views
6

Как установить локализованные имена файлов в java.Currently каждый раз, когда я нажимаю на локализованный файл, имеющий имя файла, отличного от ascii, в моем приложении, открывается диалоговое окно сохранения Windows, но оно не отображает имя файла правильно, если charset - это нечто большее, чем 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-Type и Content-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")); 
+0

DKarp, Этот код был действительно полезен. Теперь я могу получить желаемые результаты во всех браузерах, кроме IE. С IE при загрузке файла он кодирует имя файла для отображения в надлежащем формате, но добавляет к нему весь URL-адрес, и когда я пытаюсь загрузить файл .xls, он отображает окно выполнения загрузки с предупреждением об этом, в котором говорится: «Интернет Проводник не смог открыть этот сайт. Сайт либо недоступен, либо не найден. Я бы снова хотел, чтобы ты указал мне в правильном направлении. Большое спасибо за вашу помощь. – Hitatichi

+0

Какой код вы используете для настройки заголовка 'Content-Disposition' для IE? Я думаю, что некоторые версии IE могут плохо справляться с складыванием заголовков, поэтому не ставьте лишнюю строку в заголовке ... – dkarp

+0

Я использовал URLEncoder для IE точно так, как вы указали в ответе. response.addHeader («Content-Disposition», «attachment; filename =» + URLEncoder.encode (имя файла, «utf-8»)); – Hitatichi

2

Из section 2.3 in the spec, кажется, вы не можете использовать не-US-ASCII символы:

Текущая [RFC 2045] грамматику ограничивающего значения параметров (и, следовательно, Content-Disposition имена файлов) в US-ASCII. Мы признаем большую целесообразность разрешать произвольные наборы символов в именах файлов, но не входит в объем этого документа для определения необходимых механизмов . Мы ожидаем, что базовая спецификация [RFC 1521] `value ' будет впоследствии изменена, чтобы разрешить использование символов, отличных от US-ASCII , и в этот момент тот же самый механизм должен использоваться в параметре имени файла-объявления .

+0

Это является точной, но бесполезно. :) – dkarp

+0

Gustafc, Спасибо за ваше время и RFC, которые указали причину этих нежелательных результатов. – Hitatichi

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 parametr, который кодируется utf-8/win-1250 в соответствии с браузером пользователя, он должен работать.

Например, если у нас есть файл с именем omáčka.xml,
для FireFox, Opera и Chrome я Ответный этот заголовок (в кодировке UTF-8):

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

и для IE я Ответный этот заголовок (кодированным в победу-1250):

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

Java пример in my post, который упомянут выше.

Примечание # 1 (@dkarp):

знать о использовании URLEncoder.encode() так как этот метод не кодирует входной строки в URL-кодирования. Этот метод кодирует входные строки в кодировку формы, которая очень похожа, но в некоторых случаях отличается, например, символ пробела ', кодируется как «+» вместо «% 20».

Чтобы выполнить правильную кодировку URL-адрес, вы должны лучше использовать URI класс:

URI uri = new URI(null, null, "foo-ä-€.html", null); 
System.out.println(uri.toASCIIString()); 
Смежные вопросы