Spring security + i18n = как заставить работать вместе?

Мой первый вопрос здесь, и я постараюсь быть конкретным. Я совсем новичок в 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 он создает Locale без атрибута "страна" (установлен только язык). Честно говоря, я не знаю, есть ли проблема - может, нет. 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>

Таким образом, перехватчик никогда не вызывался по какой-то причине.

После изменения перехватчика def на:

<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.

Теперь проблема исчезла, но я не уверен, что случилось. Из того, что я понимаю во втором примере (тот, который работает), я сделал перехватчик "глобальным". Но почему перехватчик, определенный в первом примере, не работал? Любой намек?

Еще раз спасибо за помощь! Н.

Ответы на вопрос(1)

Ваш ответ на вопрос