2011-03-09 13 views
5

Disculpe si esta pregunta se ha formulado antes, pero no he recibido una respuesta directa que me haya ayudado a resolver mi problema. Tengo una aplicación gwt que he protegido usando Spring-Security. La seguridad de primavera solo autentica al usuario y redirige a la aplicación gwt. Ahora quiero que el usuario pueda cambiar la configuración regional desde un enlace en la página de inicio de sesión, después de lo cual la configuración regional se almacenará en una cookie y se usará en la aplicación.¿Cómo habilita LocaleInterceptor para cambiar la configuración regional en la página de inicio de sesión de seguridad de primavera?

que tienen las siguientes configuraciones, en mi 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> 

Esto no parece funcionar. Tengo los archivos de propiedades locales messages_en.properties, messages_es.properties y messages_pt.properties en mi classpath. La única vez que funciona es cuando cambio la configuración regional predeterminada de los navegadores. Por lo que puedo decir, la página de inicio de sesión la genera Spring-Security y la asignación de controlador no puede interceptar la solicitud de cambio de entorno local. Si esta es la razón, ¿cómo voy a hacer esto? La ayuda es muy apreciada.

Aquí está mi código de filtro personalizado.

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 { 

}} 

Respuesta

1

El LocaleChangeInterceptor es una parte de Spring MVC y eso significa que ellos no vienen en la imagen en filtros de seguridad de resorte. Deberá establecer la configuración regional usted mismo dentro de la cadena de filtros. Por favor, también vea Spring Security/SEC-1527: Internationalize one of the sample applications

+0

Gracias @Ritesh, tienes razón, LocaleChangeInterceptor no es parte de spring-security. Lamentablemente, la aplicación de muestra incluida con spring-security no ofrece mucha ayuda. Por lo tanto, he implementado un filtro personalizado para establecer la configuración regional dentro de la cadena de filtros específicamente antes de FORM_LOGIN_FILTER. Cuando ejecuto la aplicación, puedo ver que el filtro está registrado antes de UsernamePasswordAuthenticationFilter, pero cuando intento cambiar la configuración regional, no funciona.Aquí está mi configuración de filtro personalizada ' ' –

+0

@kibyegn Por favor, agregue el código de internationalizationFilter en la pregunta. – Ritesh

+0

He agregado el código de filtro. –

4

Gracias @Ritesh por dar la respuesta. Usted me da una idea para manejar este problema. trabajé alrededor de ella en una forma aún más:

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(); 
     } 
    } 
    } 

} 

Con declaró la localChangeInterceptor y localeResolver en el archivo de configuración MVC. para que podamos cambiar la configuración regional con la petición de parámetro "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> 

En el archivo de configuración de seguridad, hice un i18nFilter y añadió que el filtro de la cadena:

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

con localChangeInterceptor & localeResolver, Puedo cambiar la configuración regional y guardar la configuración regional en sesión o cookie.

under localeLa ayuda de Resolver, InternationalizationFilter podría almacenar/restaurar la configuración regional y realizar cambios en la configuración regional de LocaleContextHolder.

+0

Guau ... desordenado e innecesario. –

1

Primero, la clave es LocaleResolver y olvida el interceptor.

Simplemente cree un bean que implemente esta interfaz para resolver la configuración regional desde donde la guarda, como ejemplo de un atributo de la solicitud.

public class LocaleResolverImpl implements LocaleResolver { 

    public LocaleResolverImpl() { 
    } 

    @Override 
    public Locale resolveLocale(HttpServletRequest request) { 
     Locale r = (Locale) request.getAttribute("localeObject"); 
     return r == null ? request.getLocale() : r; 
    } 

    @Override 
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 
} 
+0

¿Puedes explicar más? No puedo asignar su solución a mi código. Estoy siguiendo este enlace http://www.mkyong.com/spring-mvc/spring-mvc-internationalization-example/. Quiero cambiar la configuración regional en la página de inicio de sesión. TIA. –

Cuestiones relacionadas