internationalization - 如何启用 LocaleInterceptor 在 spring-security 登录页面中更改语言环境?

标签 internationalization spring-security locale

如果之前有人问过这个问题,请原谅我,但我没有得到帮助我解决问题的直接答案。
我有一个使用 spring-security 保护的 gwt 应用程序。 Spring security 只是对用户进行身份验证并重定向到 gwt 应用程序。现在我希望用户能够从登录页面上的链接更改语言环境,之后语言环境将存储在 cookie 中并在应用程序中使用。

我的 applicationContext.xml 中有以下配置

<http auto-config="true">
    <intercept-url pattern="/mywebapp/**" access="ROLE_USER"/>
    <intercept-url pattern="/gwt/**" access="ROLE_USER"/>
    <intercept-url pattern="/**/*.html" access="ROLE_USER"/>
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <form-login login-page="/login.jsp"/>
</http>
<beans:bean id="userDetailsService"
    class="com.kibet.mywebapp.server.auth.UserDetailsServiceImpl">
</beans:bean>

...
<!-- Application Message Bundle -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <beans:property name="basename" value="classpath:messages" />
    <beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>

<beans:bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
    <beans:property name="paramName" value="lang" />
</beans:bean>

<beans:bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <beans:property name="defaultLocale" value="pt"/>
</beans:bean>

<beans:bean id="urlMapping"
     class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <beans:property name="interceptors">
    <beans:list>
        <beans:ref bean="localeChangeInterceptor"/>
    </beans:list>
    </beans:property>
    <beans:property name="mappings">
    <beans:value>/login.jsp=userDetailsService</beans:value>
    </beans:property>
</beans:bean>

这似乎不起作用。我的类路径中有语言环境属性文件messages_en.properties、messages_es.properties 和messages_pt.properties。它唯一有效的时间是当我更改浏览器默认语言环境时。
据我所知,登录页面是由 spring-security 生成的,处理程序映射无法拦截语言环境更改请求。如果这是原因,我将如何处理?非常感谢帮助。

这是我的自定义过滤器代码。
public class InternationalizationFilter implements Filter {

@Override
public void destroy() {
    // TODO Auto-generated method stub

}

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain filterChain) throws IOException, ServletException {
    String newLocale = request.getParameter("lang");
    if (newLocale != null) {
        Locale locale = StringUtils.parseLocaleString(newLocale
                .toLowerCase());
        LocaleContextHolder.setLocale(locale);
    }
    try {
        filterChain.doFilter(request, response);
    } finally {

        LocaleContextHolder.resetLocaleContext();
    }
}

@Override
public void init(FilterConfig arg0) throws ServletException {

}}

最佳答案

感谢@Ritesh 给出答案。
你给我一个想法来处理这个问题。
我以另一种方式解决了它:

public class InternationalizationFilter extends OncePerRequestFilter {
  private Logger log=Logger.getLogger(InternationalizationFilter.class);
  private String localeParam="lang";
  private LocaleResolver localeResolver;

  public InternationalizationFilter(String localeParam, LocaleResolver localeResolver) {
    this.localeParam = localeParam;
    this.localeResolver = localeResolver;
  }

  @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 {
    if (localeResolver == null) {
      throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
    }
    else{
      final String newLocale = request.getParameter(localeParam);
      if (newLocale != null) {
        final Locale locale = StringUtils.parseLocaleString(newLocale.toLowerCase());
        LocaleContextHolder.setLocale(locale);
        LocaleEditor localeEditor = new LocaleEditor();
        localeEditor.setAsText(newLocale);
        localeResolver.setLocale(request, response, (Locale) localeEditor.getValue());
        log.debug("change locale to "+
            locale.getLanguage()+"_"+locale.getCountry()+
            " at Thread"+Thread.currentThread().getId());
      }
      else{
        final Locale locale=localeResolver.resolveLocale(request);
        LocaleContextHolder.setLocale(locale);
        log.debug("restore locale to "+
            locale.getLanguage()+"_"+locale.getCountry()+
            " at Thread"+Thread.currentThread().getId());
      }
      try {
        filterChain.doFilter(request, response);
      } finally {
        LocaleContextHolder.resetLocaleContext();
      }
    }
  }

}

在 mvc 配置文件中声明了 localChangeInterceptor 和 localeResolver。
因此,我们可以使用请求参数“lang”更改语言环境:
  <mvc:interceptors>
    <bean id="localChangeInterceptor"
          class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
      <property name="paramName" value="lang"/>
    </bean>
  </mvc:interceptors>


  <!--localeResolver-->
  <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <!--<property name="cookieDomain" value=""/>-->
    <property name="defaultLocale" value="zh"/>
  </bean>

在安全配置文件中,我创建了一个 i18nFilter 并将其添加到过滤器链中:
  <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
    <security:filter-chain-map path-type="ant">
      <security:filter-chain pattern="/**/*.css" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.jpg" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.png" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.gif" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.js" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.cur" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/**/*.swf" filters="
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/login" filters="
          i18nFilter,
          securityContextPersistenceFilter,
          exceptionTranslationFilter"/>
      <security:filter-chain pattern="/checkin" filters="
          i18nFilter,
          securityContextPersistenceFilter,
          authenticationFilter"/>
      <security:filter-chain pattern="/**" filters="
           i18nFilter,
           securityContextPersistenceFilter,
           authenticationFilter,
           logoutFilter,
           anonymousAuthenticationFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />

    </security:filter-chain-map>
  </bean> 



<bean id="i18nFilter" class="com.bjinfotech.filter.InternationalizationFilter">
    <constructor-arg name="localeParam" value="lang"/>
    <constructor-arg name="localeResolver" ref="localeResolver"/>
  </bean>

使用 localChangeInterceptor 和 localeResolver,我可以更改语言环境并将语言环境保存到 session 或 cookie 中。

在 localeResolver 的帮助下,InternationalizationFilter 可以存储/恢复区域设置并更改 LocaleContextHolder 的区域设置。

关于internationalization - 如何启用 LocaleInterceptor 在 spring-security 登录页面中更改语言环境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5244776/

相关文章:

html - 泰语断线 : how to break Thai text effectively

django - Django支持哪些语言?我找不到完整的 list

internationalization - SilverStripe i18n Textcollector 任务未加载

tomcat - 如何使用 Active Directory 对 Java Web 应用程序进行单点登录

android - 如何在 Android 上更改 com.facebook.widget.LoginButton 的语言

r - fread 系统区域设置错误

c++ - 语言环境构面构造函数被忽略

Spring Boot i18n 解析

Grails Spring Security Core 注销消息

java - 将属性文件或 xml 文件中的属性值注入(inject) PreAuthorize(...) java 注释(未解决)