| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Servlet Filter глючит установка кодировки |
| Автор: dimanenok 10.4.2009, 11:32 |
| Есть проблема которая ставит меня в тупик. Уже кажется все перепробовал. Есть jsp страница, которая по факту в UTF-8 кодировке. Сервлет фильтр просто устанавливает хедер - HttpServletResponse resp = (HttpServletResponse)response; if (contentType.indexOf("text/html") > -1) { resp.setHeader("Content-Type", "text/html;charset=UTF-8"); } И все было хорошо - приходят данные в UTF-8 с заголовком Content-Type: text/html;charset=UTF-8 Но недавно размер jsp страницы превысил какойто весьма небольшой порог и метод resp.setHeader("Content-Type", "text/html;charset=UTF-8"); перестал работать. Тоесть данные приходят в UTF-8 но в заголовке шлется Content-Type: text/html;charset=ISO-8859-1 Более того - в самом фильтре после установки resp.setHeader("Content-Type", "text/html;charset=UTF-8"); метод - resp.getContentType() возвращает - text/html;charset=ISO-8859-1 Несколько раз проверял - если я делаю jsp страничку чуть меньше (я это делаю тем что убираю несколько - неважно каких - строк из файла локализации который выводится в форме JavaScript массива) - то все нормально! И resp.getContentType() возвращает - Content-Type: text/html;charset=UTF-8 после setHeader. Что я уже пробовал - 1) Пробовал добавлять <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> на страницу - никакой реакции. 2) Пробовал ставить на странице - <%@ page contentType="text/html; charset=UTF-8" %> Эта штука меняет высылаемый хедер на UTF-8 но параллельно с этим она перекодирует то что уже и так в UTF-8 еще раз в UTF-8. По видимому этот тег при парсинге интерпретирует контент который на самом деле в UTF-8 как контент в ISO-8859-1 и еще раз перекодирует в UTF-8 - получается билеберда, а мне нужно только поменять заголовок не меняя контента. 3) Пробовал вызывать resp.setHeader("Content-Type", "text/html;charset=UTF-8"); в самом коде JSP страницы - тоесть до возврата из chain.doFilter(request, response); - там этот метод работает, но почемуто также как и тег <%@ page contentType="text/html; charset=UTF-8" %> - меняет и хедер и контент. Помогите разобраться с этой чертовщиной! |
| Автор: skhilkov 10.4.2009, 12:38 | ||
Есть предположение что контент у вас не utf8.... может быть страницу в каком-нить другом редакторе открыли, или еще что... Не знаю, конечно, но вот эта штука у меня везде работает железно... если не трудно, киньте файл сюда(не содержимое, а оригинальный файл), если, конечно не секретно... |
| Автор: dimanenok 10.4.2009, 13:36 | ||||
Вот тут моя JSP страница + русскоязычный файл локализации + Еще фильтр на всякий случай - увидете там в коде как она его выводит - <% ResourceBundle messages = ResourceBundle.getBundle("Messages",new Locale((String)session.getAttribute("selectedLocale"))); ... %> Выложил сюда - http://slil.ru/27436623 Проблема перестает воспроизводиться если из Messages_ru.properties например удалить любые - не важно какие - 2 строки, тогда правильно работает resp.setHeader("Content-Type", "text/html;charset=UTF-8"); и все хорошо. PS: Может можно на этот форум напрямую файлы заливать, но не важно... |
| Автор: dimanenok 10.4.2009, 17:51 |
| Я выложил, предположение оправдалось?? !HELP! |
| Автор: Samotnik 11.4.2009, 15:22 |
| метод какой ? GET POST ? |
| Автор: dimanenok 11.4.2009, 15:44 | ||
GET /RTCrystalWeb2/main.jsp HTTP/1.1 |
| Автор: Samotnik 11.4.2009, 15:59 | ||||||||||
| так ... значит могу предложить 1-
2 -
3 -
4 -
Но это уже ты все перепробовал кстати, на оффсайте написано
может в этом и проблема ? |
| Автор: dimanenok 13.4.2009, 19:56 | ||||||||||
Видел "Currently viewing the 256 characters starting at 20a0" на офсайте, но не понял как это может быть связано с проблемой? Вобщем проблема разрешилась. Путь по которому я двигался - Да, тег <%@ page contentType="text/html; charset=utf-8" %> работает и работал - проблема была в том как работает JSTL локализация. Изначально ресурс с русскими буквами считывался в UTF-8, ничего с ним не делалось а после возврата из chain.doFilter(request, response); я ставил - resp.setHeader("Content-Type", "text/html; charset=UTF-8"); хедер добавлялся, и все было ОК. Проблема была изза того что после того как ресурс вырос почемуто перестал работать - resp.setHeader("Content-Type", "text/html; charset=UTF-8"); Но фактически никто не обязывает его работать потомучто вообще операция resp.setHeader("Content-Type", "text/html; charset=UTF-8"); после chain.doFilter(request, response); некорректна, иными словами -
- можно, а
- типа некорректно. Вобщем я сделал в фильтре -
Результат оказался такой - обычный русский текст отображался нормально а теги <fmt:message key="..."/> - крокозябрами. Как я выяснил - все изза того что <fmt:message key="..."/> считает что все файлы локализации заданы в iso-8859-1 а не UTF-8. Соответственно если у страницы кодировка не указана или указана как iso-8859-1 что эквивалентно, тогда <fmt:message key="..."/> соответственно не считает нужным ничего делать с данными - считывает в кодировке iso-8859-1 и передает не изменяя. Тогда по умолчанию отображается страница в iso-8859-1 кодировке (потому что такой шлется дефолтный чарсет в контенттайпе) - если в браузере руками поменять на utf-8 отобразится русский текст. Если же мы поставили кодировку страницы utf-8 - неважно как - resp.setCharacterEncoding("utf-8"); или <%@page contentType="text/html;charset=UTF-8"%> то <fmt:message key="..."/> начинает конвертить то что уже и так в UTF-8 еще раз в UTF-8. Как это делается - есть в файле локализации буква 'о' записанная как D0BE, коль скоро система считает что это все в iso-8859-1 то интерпретирует это как 2 символа в кодировке iso-8859-1 с кодами D0 и BE. Потом ковертит 2 символа в UTF-8 - как это делает - коды у iso-8859-1 и начальные коды UTF-8 как известно совпадают, только юникод это 2 байта, соответственно получаются 2 юникодных символа с кодами 00D0 и 00BE, получается безвыходная ситуация. Чтоб этого безобразия избежать - пришлось использовать небезизвестную штуку - C:\Program Files\Java\jdk1.6.0_03\bin>native2ascii.exe -encoding UTF-8 Messages_ru.properties Messages_ru2.properties Остается только вопрос - нафига так сделано что приходится использовать native2ascii. Почему в J2EE нельзя - а) Создавая локаль указывать в какой кодировке записан файл ресурса, или если это возможно то както очень заморочено, и никто не знает б) Или указывать после считывания ответа в фильтре - resp.setHeader("Content-Type", "text/html;charset=UTF-8"); - чтобы выставлялся хедер и не менялся контент - (фактически это получается что работает для маленьких респонсов а для больших не работает). Впрочем все это вопросы уже не сюда.. |