barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

понедельник, 16 января 2012 г.

HttpServlet: установка Content-Disposition заголовка для скачивания файла с русскими символами в имени

Проблема:
Задача следующая: отправить в браузер файл с русскими символами в имени. Проблема заключается в том, что если помещать имя файла в заголовок непосредственно кодом:
response.setHeader("Content-Disposition", "attachment; filename="+fileName);
вместо корректного имени получаем кракозябры, а IE 8 вообще выкидывает невнятное сообщение о невозможности загрузки.

Решение:
Ниже приведет кроссбраузерный код (работает в IE 8, FF 9, Opera 11.60, Chrome 16):

        if(request.getHeader("user-agent")!=null && request.getHeader("user-agent").indexOf("Firefox")!=-1) // Firefox
            response.setHeader("Content-Disposition", "attachment; filename*=utf-8''"+java.net.URLEncoder.encode(fileName, "UTF-8") + ";");
        else
            response.setHeader("Content-Disposition", "attachment; filename="+java.net.URLEncoder.encode(fileName, "UTF-8"));



3 комментария:

  1. Спасибо за предложенное решение, взял за основу. Однако, есть проблема - кодер превращает пробел в "+". Так что при скачивании файла его имя, если оно с пробелами, получается искаженным.

    Решение такое, например: до кодирования заменить в имени файла все пробелы на "*" (она не встречается в именах файлов), а после кодирования - заменить "*" на "%20"

    ОтветитьУдалить
  2. Да, и еще, если делать, как у Вас, то Firefox добавит знак подчёркивания перед именем файла (не знаю, зачем). Проблему решает добавление двойных кавычек, охватывающих весь текст после знака "=":

    value += ";filename*=\"utf-8''" + encodeFilename(rawEncodedFlnm + "\"");

    ОтветитьУдалить