Мой первый вопрос здесь, и я постараюсь быть конкретным.Я совсем новичок в Spring, и я пытаюсь создать довольно простую систему бронирования (но это на самом деле не имеет значения).Важно то, что я создаю какой-то базовый шаблон, который затем заполняю реальными веб-страницами.Приложение работает на Hibernate, MySQL, я также настроить i18n и Spring Security.Проблема в том, что я не могу изменить свой язык.Единственное, что работает, это изменение по умолчанию.Сначала я просмотрел Web A LOT и обнаружил, что использование i18n вместе с Spring Security сложнее, чем обычно.Я обнаружил, что мне нужен дополнительный фильтр:
<filter>
<filter-name>localizationFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>localizationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Я обнаружил, что этот фильтр действительно обрабатывается перед защитным, однако он не анализирует запрос в форме: http://someserver.com/bla/home?locale=en
.Я отладил его, и кажется, что он не создан для этой цели (и это то, что мне нужно).Это взято из весенних примеров "контактов", однако в этом примере я не смог найти никакого кода, который на самом деле предназначался для изменения языка.В результате он просто не работает.Он всегда пытается изменить локаль на мою по умолчанию.Хорошая новость заключается в том, что если в режиме отладки я вручную изменил локаль-набор на другой, он работал нормально, поэтому я чувствовал надежду в моем сердце ...; -)
Тогда я нашел несколькоДругой способ - создав собственный фильтр.Что я сделал, так это слил найденный пример (не помню автора) и способ создания RequestContextFilter
.В конце концов, RequestContextFilter
работает нормально - просто не разбирайте мои запросы.Это код нового фильтра:
public class InternationalizationFilter extends OncePerRequestFilter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
protected void doFilterInternal(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain filterChain)
throws ServletException, IOException {
final String newLocale = request.getParameter("locale");
if (newLocale != null) {
final Locale locale = StringUtils.parseLocaleString(newLocale
.toLowerCase());
LocaleContextHolder.setLocale(locale);
}
try {
filterChain.doFilter(request, response);
} finally {
LocaleContextHolder.resetLocaleContext();
}
}
}
Как видите, локаль параметра запроса анализируется и локаль установлена.Есть 2 проблемы: 1. После отправки запроса xxxxx?locale=en
создается языковой стандарт без атрибута «страна» (задается только язык).Честно говоря, я не знаю, есть ли проблема - может, нет.2. Более серьезная проблема заключается в том, что он не работает ... я имею в виду, что он находится в нужном месте в цепочке фильтров (до защиты), он производит правильную локаль и устанавливает ее точно так же, как RequestContextFilter
... но это просто не работает.
Я был бы очень рад, если бы кто-нибудь мог дать мне знать, как заставить i18n работать с пружинной защитой на основе моего примера или любого другого ...
Спасибо!
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Я провел несколько экспериментов, и кажется, что экземпляр Locale из запроса как-то специфичен.
Посмотрите на этот код (изменил класс RequestContextFilter
):
@Override
protected void doFilterInternal(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain filterChain)
throws ServletException, IOException {
final ServletRequestAttributes attributes = new ServletRequestAttributes(
request);
final Locale l = Locale.GERMAN;
final Locale l2 = request.getLocale();
LocaleContextHolder.setLocale(l,
this.threadContextInheritable);
RequestContextHolder.setRequestAttributes(attributes,
this.threadContextInheritable);
if (logger.isDebugEnabled()) {
logger.debug("Bound request context to thread: " + request);
}
(...)
если для этого метода: LocaleContextHolder.setLocale(l, this.threadContextInheritable);
я передаю язык 'l', он вообще не работает.Я имею в виду, что локаль не меняется, даже если она явно изменилась.С другой стороны, если я передам там Locale 'l2', который изменен на немецкий (в режиме отладки), он работает нормально!
Это означает, что по какой-то причине экземпляр Locale из request.getLocale()
почему-то предпочтителен, возможно,что-то происходит позже в коде, который я не знаю / не знаю ...
Пожалуйста, дайте мне знать, как я должен использовать этот i18n вместе с соображениями безопасности, я дошел до того, что должен признать, чтоЯ понятия не имею, что происходит ...
- ==== - ====== - ====== - ======= - ====
ЗАКЛЮЧИТЕЛЬНОЕ РЕШЕНИЕ / ОТВЕТ (но все еще без особых вопросов) Благодаря Ральфу мне удалось исправить мою проблему.Раньше я шел в неправильном направлении, но сгенерированный руом проект подтолкнул меня вперед.Кажется, что я продолжал добавлять перехватчик неверным / не точным способом (предыдущий код):
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="pl"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<ref bean="localeChangeInterceptor" />
</property>
</bean>
Таким образом перехватчик никогда не вызывался по какой-то причине.
После изменения перехватчика defto:
<mvc:interceptors>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
</bean>
</mvc:interceptors>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="pl"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
</bean>
... он начал нормально работать без каких-либо других изменений в security / web.xml.
Теперь проблема исчезла, но я не уверен, что случилось.Из того, что я понимаю во втором примере (тот, который работает), я сделал перехватчик "глобальным".Но почему перехватчик, определенный в первом примере, не работал?Любой намек?
Еще раз спасибо за помощь!Н.