6

Mi primera pregunta aquí y trataré de ser específico. Soy bastante nuevo en Spring y estoy tratando de crear un sistema de reservas bastante simple (pero esto en realidad no importa). Lo que importa es que estoy creando una plantilla básica que luego completaré con páginas web reales. La aplicación funciona en hibernate, mysql, también configuro i18n y seguridad de primavera. El problema es que no puedo cambiar mi configuración regional. Lo único que funciona es cambiar el predeterminado. Primero busqué Web MUCHO y descubrí que el uso de un i18n junto con la seguridad de primavera es más complicado que generalmente. Lo que descubrí es que necesito tener filtro adicional:Seguridad de primavera + i18n = ¿cómo hacerlo funcionar juntos?

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

Lo que descubrí es que este filtro es de hecho procesada antes de que la seguridad único sin embargo, no analiza la petición en un formulario: http://someserver.com/bla/home?locale=en. Lo depuré y parece que no fue creado para tal fin (y eso es lo que necesito). Esto se toma de los "contactos" de muestra de primavera, sin embargo, en este ejemplo, no pude encontrar ningún código que realmente estuviera destinado a cambiar el idioma. El efecto es que simplemente no funciona. Siempre trata de cambiar la configuración regional a la predeterminada. La buena noticia es que si en el modo de depuración cambiaba manualmente la configuración regional a otra, funcionaba bien, así que sentí la esperanza en mi corazón ... ;-)

Luego he encontrado otra manera - creando nuestro propio filtro. Lo que hice fue fusionar el ejemplo encontrado (no recuerdo al autor) junto con la forma en que se creó RequestContextFilter. Después de todo, el RequestContextFilter funciona bien, simplemente no analice mis solicitudes. Eso es código del nuevo filtro:

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

} 

Como se puede ver la configuración regional solicitud parametro se analiza y la configuración regional está establecida. Hay 2 problemas: 1. Después de enviar la solicitud xxxxx?locale=en, crea la configuración regional sin el atributo "país" (solo se establece el idioma). Para ser honesto, no sé si hay algún problema, tal vez no. 2. El problema más grave es que no funciona ... me refiero a que está en el lugar correcto de la cadena de filtros (antes de la de seguridad), produce la configuración regional correcta y la configura de la misma manera que RequestContextFilter. .. pero simplemente no funciona.

Yo sería muy feliz si alguien puede que me haga saber cómo hacer que el trabajo con i18n-basar la seguridad de primavera en mi ejemplo dado o cualquier otro ...

Gracias!

INFORMACIÓN ADICIONAL: Realicé algunos experimentos y parece que la instancia de Locale from request es de alguna manera específica.

mirada a este código (modificado la clase 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); 
    } 
(...) 

si este método: LocaleContextHolder.setLocale(l, this.threadContextInheritable); que pase locale 'l' no funciona en absoluto. Quiero decir que la configuración regional no cambia aunque haya cambiado explícitamente. Por otro lado, si paso allí Locale 'l2' que está modificado para alemán (en modo de depuración) ¡funciona bien!

Esto significa que por alguna razón la instancia de configuración regional de request.getLocale() es de alguna manera favorecida, tal vez algo está pasando más adelante en el código que no sé/understant ...

Por favor, hágamelo saber cómo debe Utilizo este i18n junto con la seguridad porque llegué al punto en el que debo admitir que no tengo idea de lo que está pasando ...

- ==== - ====== - ====== - ======= - ====

solución final/RESPUESTA (pero aún con poca pregunta) Gracias a Ralph Logré solucionar mi problema. Anteriormente iba en la dirección equivocada, pero el proyecto generado por roo me empujó hacia adelante. Parece que seguía añadiendo el interceptor en un/a mal no es exacta (código anterior):

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

De esta manera el interceptor nunca fue invocado por alguna razón.

Después de cambiar interceptor def a:

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

... Comenzó a trabajar bien sin ningún otro cambio en la seguridad/web.xml.

Ahora el problema se ha ido sin embargo, no estoy seguro de lo que pasó. Por lo que entiendo en el segundo ejemplo (el que funciona) hice el interceptor "global". Pero ¿por qué el interceptor definido en el primer ejemplo no funcionó? ¿Alguna pista?

¡Gracias nuevamente por su ayuda! N.

+0

Hola ... He intentado con tu configuración de interceptor, pero no funciona. Mi configuración regional no cambia en la página de inicio de sesión. Pero después de iniciar sesión correctamente, funciona bien. En la página de inicio de sesión, solo aparece en la configuración regional del sistema. –

Respuesta

1
  1. Después de enviar la solicitud xxxxx? Locale = es que crea Locale sin "país" (sólo se establece el idioma) atributo.

Es el comportamiento esperado. En java hay algún tipo de jerarquía. El idioma es más general que el país.

La idea detrás de esto es que puede tener, por ejemplo, el texto en el lenguaje más común pero algunas unidades (como la moneda) en los archivos específicos del país.

@see: http://java.sun.com/developer/technicalArticles/Intl/IntlIntro/


  1. El problema más grave es que no funciona ...

Se debe trabajar sin ningún tipo de hechos a mano la aplicación!

Debe registrar el Interceptor de cambio local, y debe establecer permitAll para la página de inicio de sesión.

<mvc:interceptors>   
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/> 
</mvc:interceptors> 

<http auto-config="true" use-expressions="true"> 
    <form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t"/> 
    <logout logout-url="/resources/j_spring_security_logout"/> 

    <!-- Configure these elements to secure URIs in your application --> 
    <intercept-url pattern="/login" access="permitAll" /> 
    <intercept-url pattern="/resources/**" access="permitAll" /> 
    <intercept-url pattern="/**" access="isAuthenticated()" /> 
</http> 

Para ver este ejemplo correr, crear un proyecto Roo con ese guión Roo:

// Spring Roo 1.1.5.RELEASE [rev d3a68c3] log opened at 2011-12-13 09:32:23 
project --topLevelPackage de.humanfork.test --projectName localtest --java 6 
persistence setup --database H2_IN_MEMORY --provider HIBERNATE 
ent --class ~.domain.Stuff 
field string --fieldName title 
controller all --package ~.web 
security setup 
web mvc language --code de 
web mvc language --code es 

Entonces sólo tiene que cambiar los filtros de seguridad Intersept-url patrones como he mostrado anteriormente (applicationContext-security.xml)!

Ahora usted tiene una aplicación en la que el usuario puede cambiar su local a través del cambio interceptor local en la aplicación (cuando el usuario está conectado), así como cuando no está conectado (en la página de inicio de sesión)

+0

Ok gracias por la respuesta rápida, eso es lo que esperaba. Tal vez podrías ponerme en el camino correcto también en el caso del problema principal (cambio de configuración regional). ¡Gracias de nuevo! – Nirwan

+0

@Nirwan: vea mi respuesta extendida: realmente no explica por qué no funciona para usted, pero lo guía a un ejemplo donde el interceptor de cambio local funciona bien. – Ralph

+0

gracias Ralph. Con el ejemplo de roo logré que funcionara finalmente. Como ha dicho, no había necesidad de implementación manual ... Consulte mi pregunta para obtener más información sobre lo que estuvo mal, tal vez pueda decirme lo que en realidad causé, no estoy seguro;) De todos modos, ¡gracias de nuevo! ! – Nirwan

0

Tuve un problema similar con la localización cuando estaba trabajando con la aplicación GWT. El problema que noté fue que cuando asignamos

<filter-mapping> 
<filter-name>localizationFilter</filter-name> 
<url-pattern>/*</url-pattern> 
</filter-mapping> 

al filtro, las solicitudes de imágenes pares se enrutan al filtro. En ocasiones, estas solicitudes omiten el parámetro de configuración regional y, por lo tanto, cuando varias solicitudes llegan al filtro, el parámetro Configuración regional no. Por lo tanto, tan pronto como recibí el parámetro locale, lo puse en una sesión. Registre todos los encabezados de solicitud y los valores, y puede encontrar la causa raíz.

Cuestiones relacionadas