Проблемы с кодированием при миграции Apache Velocity
Я уже много лет использую Apache Velocity на своей веб-платформе Tomcat.
У меня были очень старые версии: Velocity-1.6.4 и Speed-Tools-1.4, и недавно я решил перенести всю свою платформу и использовать Speed-Engine 2.3 и Speed-Tools 3.1.
Поскольку у меня около 15 веб-приложений, процесс был немного долгим, но довольно простым. К сожалению, у меня есть некоторые проблемы с рендерингом, особенно:
- Знак евро € отображается неправильно.
- Когда веб-страница загружает внешние скрипты с метками (ударения на французском языке, специальные символы), они кажутся символами ANSI.
Вот какие вещи я получаю:
Ударения, доллар, пунктуация: àèù, $, ! ?,
Знак евро: ?
Из внешнего js: éà èù $##!?€
Тот же шаблон, с той же конфигурацией tomcat, но с очень старыми версиями скорости отлично отображается . Если использовать простой HTML, он также работает (коннекторы в файле конфигурации Tomcat server.xml имеют точную UTF-8).
Все в UTF-8. Сервер скорости — это базовый «сервлет скорости», максимально простой. В последних версиях Velocity файл конфигурации свойств скорости содержит только:
ресурс.лоадерс = веб-приложение
ресурс.loader.webapp.class = org.apache.velocity.tools.view.WebappResourceLoader
ресурс.loader.webapp.path = /WEB-INF/templates/
Я проверил код внутри сервлета, что свойство getVelocityProperty(RuntimeConstants.INPUT_ENCODING, RuntimeConstants.ENCODING_DEFAULT) было UTF-8.
После ночей и дней, проведенных над этой проблемой, я чувствую себя в полном отчаянии! Спасибо за помощь.
2 ответа
Я нашел свою проблему! Мой «Фильтр кодировки» не фильтровал «ответ», а только запрос. Однако меня озадачивает код метода initRequest класса VelocityViewServlet:
protected void initRequest(запрос HttpServletRequest, ответ HttpServletResponse) выдает IOException{try{request.setCharacterEncoding(getVelocityProperty(RuntimeConstants.INPUT_ENCODING, RuntimeConstants.ENCODING_DEFAULT));
}
catch (UnsupportedEncodingException uee)
{
error(request, response, uee);
throw uee;
}
}
Интересно, почему Velocity не применяет setCharacterEncoding к ответу. И только по запросу. Я бы интуитивно добавил строку response.setCharacterEncoding:
В старой версии Velocity у нас было 2 параметра конфигурации: input.encoding=UTF-8 output.encoding=UTF-8.
А теперь только один: resources.default_encoding=UTF-8. Но его следует применять и к запросу, и к ответу. Я упускаю какой-то момент?
Сегодня у меня возникла та же проблема, наконец, я переопределил защищенный метод setContentType в своем классе VeloServlet, и проблема была решена:
public class MyVeloServlet extends VelocityViewServlet {
...
@Override
protected void setContentType(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/html; charset=UTF-8");
}
}
Этого результата можно достичь с помощью конфигурационного ключа в файле Velocity.properties:
default.contentType=text/html; charset=UTF-8