Подтвердить что ты не робот

Почему мой сервлет не отвечает на запросы JSON в UTF-8?

Мой сервлет просто не будет использовать UTF-8 для ответов JSON.

MyServlet.java

public class MyServlet extends HttpServlet {

  protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception {

    PrintWriter writer = res.getWriter();

    res.setCharacterEncoding("UTF-8");
    res.setContentType("application/json; charset=UTF-8");

    writer.print(getSomeJson());
  }
}

Но специальные символы не отображаются, и когда я проверяю заголовки, что я возвращаюсь в Firebug, я вижу Content-Type: application/json;charset=ISO-8859-1.

Я сделал grep -ri iso . в моем каталоге Servlet и ничего не придумал, поэтому я не устанавливаю явно тип ISO-8859-1.

Я также должен указать, что я запускаю это на Tomcat 7 в Eclipse с целью J2EE в качестве среды разработки, с Solaris 10 и тем, что они называют своей средой веб-сервера (кто-то другой администратором) в качестве рабочей среды, и поведение одинаковое.

Я также подтвердил, что представленный запрос - это UTF-8, и только ответ - ISO-8859-1.

Update

Я изменил код, чтобы отразить, что я вызываю PrintWriter, прежде чем установить кодировку символов. Я проигнорировал это из моего первоначального примера, и теперь я понимаю, что это стало причиной моей проблемы. Я прочитал здесь, что вам нужно установить кодировку символов, прежде чем вы вызовете HttpServletResponse.getWriter(), или getWriter установит его для ISO-8859-1 для вас.

Это была моя проблема. Поэтому приведенный выше пример должен быть скорректирован на

public class MyServlet extends HttpServlet {

  protected void doPost(HttpServletRequest req, HttpServletResponse res) throws Exception {

    res.setCharacterEncoding("UTF-8");
    res.setContentType("application/json");

    PrintWriter writer = res.getWriter();
    writer.print(getSomeJson());
  }
}
4b9b3361

Ответ 1

Как только кодировка задана для ответа, ее нельзя изменить.

Самый простой способ заставить UTF-8 создать свой собственный фильтр, который первым заглянет в ответ и установить кодировку.

Посмотрите как Spring 3.0 делает это. Даже если вы не можете использовать Spring в своем проекте, возможно, вы можете получить вдохновение (убедитесь, что политика вашей компании позволяет вам получить вдохновение от лицензий с открытым исходным кодом).

Ответ 2

Код выглядит отлично. Либо вы не используете код, который, по вашему мнению, вы используете, либо там Filter или прокси-сервер где-то в цепочке запроса-ответа, которая модифицирует тип контента, подобный этому.

Ответ 3

Помимо конкретной проблемы, вы действительно должны рассмотреть возможность получения потока данных, используя библиотеку JSON для записи содержимого непосредственно в кодировке JSON, кодированной UTF-8; нет никакой пользы для использования писателей. Некоторые пакеты JSON работают только со строками, что является неудачным, но большинство из них позволяют использовать более эффективные потоки (более безопасные и эффективные, поскольку парсер/генератор может обрабатывать аспекты экранирования и кодирования вместе).