Учим Apache Tomcat понимать UTF-817 марта 2010 06:47, комментариев нет

Памятки, Разработки

Судя по большому количеству запросов в Гугле, многие веб-программисты сталкиваются с проблемой неправильного кодирования данных при попытке использования UTF-8 в Apache Tomcat. Суть проблемы такова, что внутренняя кодировка Tomcat умолчанию - ISO-8859-1. То есть, текст, переданный из формы (неважно методом post или get) будет автоматически неявно перекодирован в ISO-8859-1 и окажется нечитаемым. Такая же участь ожидает текст, выводящийся наружу через Writer.

Существует несколько вариантов решения. Первый - прямое преобразование кодировки типа:

String arg = new String (arg.getBytes ("UTF-8"), "ISO-8859-1")

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

Самый правильный, на мой взгляд, вариант решения - комплексный. Первое, что надо сделать, это добавить в параметры используемого коннектора Tomcat директиву URIEncoding="UTF-8" в файле server.xml и перезапустить Tomcat. Но одной этой меры недостаточно. Второе, в сервлетах, печатающих текст, необходимо добавить три строки в таком порядке:

response.setContentType ("text/html; charset=UTF-8");
PrintWriter out = response.getWriter ();
request.setCharacterEncoding ("UTF-8");

Для ничего не печатающих сервлетов достаточно только последней строчки.

Для правильно принятия текста в JSP и JSPX можно использовать тег fmt из набора JSTL. Здесь нужно добавить в начало файла директиву

<fmt:requestEncoding value="UTF-8" />

Это позволяет принимать данные в нужной кодировке. Для JSP и JSPX, которые не принимают данные, использования тега fmt не требуется. Но этого тоже недостаточно. Тег fmt основывается на кодировке локали браузера клиента, но не все браузеры правильно передают локаль в HTTP-запросе. При невозможности получить локаль от клиента, экземпляр тега берёт данные о кодировке из параметра javax.servlet.jsp.jstl.fmt.request.charset, которая по умолчанию соответствует кодировке системы, где работает Tomcat. Чтобы такого не случилось, нужно явно определить значение данного параметра в дескрипторе развертывания вот так:

<context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.request.charset</param-name>
    <param-value>UTF-8</param-value>
</context-param>

Теперь все данные будут попадать в веб-приложение в UTF-8. Но для правильного вывода текста в JSP и JSPX описанных мер недостаточно. Необходимо добавить в JSP первой строкой:

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

А для JSPX сразу после директив jsp:root и jsp:output doctype-root-element добавить такие строки:

<jsp:directive.page contentType="text/html; charset=UTF-8" />
<jsp:directive.page pageEncoding="UTF-8" />

Вот только теперь все данные в обе стороны будут в кодировке UTF-8.

Добавьте свой комментарий

К этой статье пока нет комментариев. Но если вам есть, что сказать, вы можете оставить здесь и свой комментарий. Поля имя и почтовый адрес обязательны для заполнения. Адрес на сайте не публикуется.

Цитаты оформляются так: /* Цитируемый текст */.