Изменяет ли myfaces ExtensionsFilter кодировку страницы?
Вопрос
два дня назад я начал использовать компоненты Tomahawk ExtensionsFilter в своем jsf-приложении.Я заметил, что все оповещения JavaScript не отображают специальные символы (ç, ã, ó ô), вместо этого отображаются такие символы, как #231.Когда я удаляю ExtensionsFilter из файла web.xml, JavaScript отображается нормально.У кого-нибудь была эта проблема раньше?
заранее спасибо.
РЕДАКТИРОВАТЬ:мне удалось решить проблему, создав фильтр перед ExtensionFilter, этот новый фильтр принудительно устанавливает кодировку ЗАПРОСА в utf-8.Но это уродливое решение, лучшим решением, как сказал balusC, было бы избавиться от всего встроенного javascript.
Спасибо всем за помощь!
Решение
Еще несколько идей:
- добавить фильтр, который вызывает setContentType или setCharacterEncoding и который находится перед всеми остальными фильтрами
- установить свойство
-Dfile.encoding
- перепривязать JavaScript
window.alert
чтобы он экранировал символы
Кажется, это работает, но это будет очень и очень некрасивый хак.Это также будет очень ограничено и не будет работать, если javascript устанавливает другие тексты, например.содержание div
.
var hack = window.alert;
window.alert = function( text ) {
hack( text + ' was converted' );
};
alert('hello');
ОБНОВЛЯТЬ:
Вот подозрительная последовательность:
1) РасширенияФильтр перехватывает запрос
2) Фильтр расширений содержит
154 // only parse HTML responses
155 if (extendedResponse.getContentType() != null && isValidContentType(extendedResponse.getContentType()))
156 {
...
172 // writes the response
173 addResource.writeResponse(extendedRequest, servletResponse);
174 }
175 else
176 {
178 byte[] responseArray = extendedResponse.getBytes();
180 if(responseArray.length > 0)
181 {
182 // When not filtering due to not valid content-type, deliver the byte-array instead of a charset-converted string.
183 // Otherwise a binary stream gets corrupted.
184 servletResponse.getOutputStream().write(responseArray);
185 }
3) Дефолтаддресаурце использует Хтмлреспонсритеримпл который использует Юникодэнкодер.
4) Затем кодируются все «неосновные латинские символы».
Заключение
- если вы установите недопустимый тип контента, ExtensionsFilter по умолчанию будет использовать ветку «else» и не будет кодировать ответ.Но тогда ExtensionsFilter, вероятно, сломан.
- изменение setCharacterEncoding, вероятно, не имеет никакого эффекта, ни
file.encoding
- создание дополнительного фильтра для повторной упаковки ответа и возврата некоторых из
&#xx;
может работать, но это очень некрасиво.
У меня сейчас нет других идей, но меня интересует ответ, поскольку я также столкнулся с проблемой кодирования, которая меня раздражала.
ОБНОВЛЕНИЕ 2:
Вы могли бы попробовать АспектJ изменить только ту часть библиотеки MyFaces, которая относится к форме кодирования внутри фильтра.По моему пониманию cflow
и call
Pointcut, что-то подобное может перехватить кодировку, когда она происходит из фильтра.Если это определение создает другие помехи в обработке запроса, вы можете также рассмотреть возможность вызова addResource.writeResponse
чтобы еще больше ограничить точечный разрез.
public aspect SkipEncoding {
pointcut encodingInExtFilter() :
cflow( * org.apache.myfaces.webapp.filter. ExtensionsFilter.doFilter(..) ) &&
call ( String UnicodeEncoder.encode( String, bool, bool ));
around( String s, bool b1, bool b2 ) : encodingInExtFilter
{
return s; // skip encoding
}
}
Другие советы
Он экранирует объекты XML.Однако также считается плохой практикой вставлять код Javascript в файл JSP/XHTML.Вынесите его в отдельный файл, который вы указываете в <script src="path/to/file.js"></script>
(по крайней мере, его URL не должен попадать под фильтр), и эта конкретная проблема должна исчезнуть.
Кстати, есть ли что-нибудь из этого на ваших страницах jsp:
<?xml version="1.0" encoding="utf-8"?>
или
<%@ page pageEncoding="utf-8" %>