несоответствие кодировки между главной страницей и диалогом додзё

У меня возникла странная ситуация с кодировкой, при которой сама html-страница отображается так, как должна (со всеми символами с диакритическими знаками, правильно отображенными), но все всплывающие диалоги додзё не используют правильную кодировку.

Вот настройка:

  • веб-проект Java с Hibernate/Spring/Struts2, работающий на Tomcat6.0.18; страницы генерируются в виде плиток JSP, собранных вместе с помощью Tiles2.
  • все исходные файлы имеют кодировку UTF-8, за исключением файлов свойств ресурсов (*.properties), которые соответствуют стандарту ISO-8859-1 (согласно спецификациям Java).
  • База данных имеет кодировку UTF-8.
  • struts.xml содержит определение константы:

    <constant name="struts.i18n.encoding" value="UTF-8"/>
    
  • Каждая плитка JSP начинается с оператора

    <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
    
  • Каждая страница JSP (состоящая из нескольких плиток) начинается с оператора

    <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
    <?xml version="1.0" encoding="UTF-8"?>
    
  • Каждая HTML-страница, сгенерированная из кода JSP, содержит следующий метатег <head>:

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    
  • Фильтр кодирования Tomcat устанавливает заголовок для every single request going through Tomcat в значение:

    text/html;charset=UTF-8
    
  • dojo 1.2.3 инициализируется на каждой странице оператором

    <script type="text/javascript" src="/scripts/dojo/dojo/dojo.js" djConfig="parseOnLoad:true,usePlainJson:true,locale:'fr'"></script>
    
  • Сначала создается dijit.Dialog, а затем открывается с помощью следующих операторов (URL-адрес действия /votingOptions возвращает фрагмент JSP, который следует тем же спецификациям, что и ранее — этот фрагмент JSP в конечном итоге встраивается в <div> диалогового окна):

    dialog = new dijit.Dialog({title:"My title",loadingMessage:"Loading..."});
    dialog.setHref('/votingOptions');
    dialog.show();
    

В результате всей этой настройки на всех «обычных» страницах (то есть, если не принимать во внимание диалоги додзё) все символы отображаются как положено, с акцентами и прочим, независимо от того, исходит ли текст из базы данных или из файлов ресурсов.

С другой стороны, содержимое любого диалогового окна додзё искажается: все символы без диакритических знаков в порядке, но символы с диакритическими знаками отображаются точно так, как если бы кто-то пытался прочитать символы UTF-8 как символы ISO-8859-1 (будь то эти символы поступают из базы данных или из файлов ресурсов).

Так, например, имя «Курт Гёдель» (которое правильно отображается на главной странице) будет отображаться как «Курт Гёдель» в диалоговом окне додзё. !

Обратите внимание, что Firebug выдает те же заголовки ответа, что и Tomcat, в обеих ситуациях (будь то вызов главной страницы или открытие диалогового окна dojo на странице):

Server: Apache/2.2.3 (CentOS)
Content-Language: en-US
Connection: close
Content-Type: text/html;charset=UTF-8

Единственная разница между этими двумя типами запросов (кроме Content-Length):

Transfer-Encoding: chunked

который присутствует при запросе главной страницы, но отсутствует в случае dojo-dialog.

Кто-нибудь может понять, что ускользнуло от меня до сих пор? В качестве альтернативы, будут приветствоваться предложения относительно того, что я должен выполнить, чтобы добраться до сути этого!


person pierdeux    schedule 07.02.2009    source источник


Ответы (2)


Виджет Dialog в Dojo вызывает URL-адрес /votingOptions, который, как я полагаю, обрабатывается сервлетом или действием Struts.

Поскольку это вызов Ajax, я также предполагаю, что если вы используете действие struts, то вы отправляете ответ через объект HttpServletResponse вместо перенаправления в представление.

В любом случае обязательно используйте:

String str = "こんにちわ、 Kürt Gödel";
response.getWriter().write(str);

вместо:

response.getOutputStream().println(str);

Я смог воспроизвести поведение, которое вы испытали с этими фрагментами кода. Первый показывает все символы правильно (даже японские!), второй показывает искаженное сообщение.

Поскольку вы разрабатываете приложение Ajax, обязательно установите HttpFox плагин, который лучше показывает Http-трафик, чем Firebug.

person Leonel    schedule 16.02.2009

У меня была похожая проблема.
В моем случае файлы javascript dojo возвращались в формате iso-8859-1. Чтобы исправить это, мне пришлось переопределить метод getContentType() в классе FilterDispatcher по умолчанию. Я заменил его на следующий код (проверено в Struts 2.0.9):


protected String getContentType(String name) {
        if (name.endsWith(".js")) {
            return "text/javascript;charset=\"UTF-8\"";
        } else if (name.endsWith(".css")) {
            return "text/css";
        } else if (name.endsWith(".html")) {
            return "text/html;charset=\"UTF-8\"";
        } else if (name.endsWith(".txt")) {
            return "text/plain";
        } else if (name.endsWith(".gif")) {
            return "image/gif";
        } else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) {
            return "image/jpeg";
        } else if (name.endsWith(".png")) {
            return "image/png";
        } else {
            return null;
        }
}
person Guillermo Vasconcelos    schedule 12.08.2009