У меня недавно была проблема с кодированием веб-сайтов, сгенерированных сервлетом, который произошел, если сервлеты были развернуты под Tomcat, но не под Причалом. Я делал с этим определенное исследование и упростил проблему до следующего сервлета:
public class TestServlet extends HttpServlet implements Servlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/plain");
Writer output = response.getWriter();
output.write("öäüÖÄÜß");
output.flush();
output.close();
}
}
Если я развертываю это под Причалом и направляю браузер к нему, он возвращает ожидаемый результат. Данные возвращаются как ISO-8859-1 и если я смотрю в заголовки, затем Гагатовые возвраты:
Content-Type: text/plain; charset=iso-8859-1
Браузер обнаруживает кодирование от этого заголовка. Если я развертываю тот же сервлет в Tomcat, браузер разоблачает странные символы. Но Tomcat также возвращает данные как ISO-8859-1, различие, что никакой заголовок не говорит об этом. Таким образом, браузер должен предположить кодирование, и это идет не так, как надо.
Мой вопрос, то поведение Tomcat корректно или ошибка? И если это корректно, как я могу избежать этой проблемы? Несомненно, я могу всегда добавлять response.setCharacterEncoding("UTF-8");
к сервлету, но это означает, что я установил фиксированное кодирование, что браузер мог бы или не мог бы понять. Проблема более релевантна, если никакой браузер, но другой сервис не получает доступ к сервлету. Таким образом, как я должен иметь дело с проблемой самым гибким способом?
Если вы не укажете кодировку, для спецификации сервлета требуется ISO-8859-1. Тем не менее, AFAIK не требует, чтобы контейнер устанавливал кодировку в типе контента, по крайней мере, если вы установите его на «text / plain». Вот что сказано в спецификации:
Вызов setContentType устанавливает кодировку символов , только если данная строка типа содержимого предоставляет значение для атрибута charset.
Другими словами, только если вы установите такой тип содержимого
response.setContentType("text/plain; charset=XXXX")
Tomcat требуется для установки кодировки. Я не пробовал, работает ли это.
В общем, я бы рекомендовал всегда устанавливать кодировку UTF-8 (поскольку это вызывает наименьшие проблемы, по крайней мере, в браузерах), а затем, для текста / простого, явно указывать кодировку, чтобы браузеры не с использованием системного значения по умолчанию.
Если вы не укажете кодировку, Tomcat может кодировать ваши символы по своему усмотрению, а браузер может угадать, какую кодировку выбрал Tomcat. Вы правы в том, что способ решения проблемы - response.setCharacterEncoding ("UTF-8")
.
Вам не следует беспокоиться о вероятности того, что браузер не поймет кодировку, поскольку практически все браузеры, выпущенные за последние 10 лет, поддерживают UTF-8. Хотя, если вы действительно беспокоитесь, вы можете проверить заголовки «Accept-Encoding», предоставленные пользовательским агентом.