spring - 过滤器 null 中的 LocaleResolver 仍显示它已 Autowiring ! Spring MVC 3.1.1/Spring 安全 3.1.0

标签 spring spring-mvc localization filter spring-security

我正在使用 Spring Security 3.1.0 和 Spring MVC 3.1.1。 我希望能够根据 URL 更改区域设置,即:

http://localhost:8080/abc?lang=fr

现在,这在“正常”情况下有效,即从一个页面转到另一个页面,但是,在我的应用程序中,如果我从非安全页面转到安全页面,它首先会访问我的登录页面,由Spring Security 在到达我想要的页面之前。

这是正常的 Spring Security 行为(拦截安全资源),因此这种行为没有问题。

问题在于,当我到达安全页面时,区域设置没有改变!它保留为默认区域设置。即 ..e lang=fr 未解析出来。

我已经在dispatcher-servlet.xml 内部和外部在应用程序上下文文件中定义了与区域设置相关的bean,以执行以下操作:

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

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" p:defaultLocale="en" />

我还尝试拆分上述 2 个 bean,在应用程序上下文配置中只包含 localResolver

我对此进行了大量的研究,基本上,我知道我需要手动更改区域设置。

甚至 Spring Security 3.1.0 的 Spring 文档也说您需要自己的“过滤器”,或者可以使用 RequestContextFilter。但是,RequestContextFilter 不会解析查询字符串中的区域设置参数。

Spring Security relies on Spring's localization support in order to actually lookup   
the appropriate message. In order for this to work, you have to make sure that the 
locale from the incoming request is stored in Spring's 
org.springframework.context.i18n.LocaleContextHolder. Spring MVC's DispatcherServlet 
does this for your application automatically, but since Spring Security's filters are 
invoked before this, the LocaleContextHolder needs to be set up to contain the correct 
Locale before the filters are called.  You can either do this in a filter yourself 
(which must come before the Spring Security filters in web.xml) or you can use 
Spring's RequestContextFilter.

我想在请求到达 Controller 之前拦截该请求,因此,我编写了自己的过滤器。

基于其他人所做的事情,我的解决方案是 Autowiring LocaleResolver。当 tomcat 启动时,它在我的日志中显示“localeResolver”已 Autowiring (否则应用程序将在那里失败)但是在运行时,localeResolver 为 NULL。

再次,有帖子说要在应用程序上下文中定义 LocaleResolver...我已经这样做了,但当请求发生时我仍然得到一个 null LocaleResolver。

有什么想法吗?非常感谢。

附:我定义的过滤器位于 Spring Security 过滤器之前。我可以调试它,它首先命中它,然后由于 LocaleResolver 上的 NPE 而死掉。

感谢这个,谢谢。

最佳答案

您是否在 web.xml 中定义了过滤器?如果是这样,那么该过滤器类不是由 Spring 实例化的,而是由 servlet 容器实例化的。 Spring 无法 Autowiring 它不知道的内容。

这里的一般解决方案是声明 <filter-class>在 web.xml 中为 org.springframework.web.filter.DelegatingFilterProxy 并指向targetBeanName在您的上下文中的 bean 处,例如:

<filter>
    <filter-name>My Locale Filter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>myLocaleFilter</param-value>
    </init-param>
</filter>

在 Spring 上下文中,<bean id="myLocaleFilter">应该指向您的 Filter 类。

您可能还会发现自定义 Filter 类扩展 GenericFilterBean 很方便而不是实现 Filter直接接口(interface)。

关于spring - 过滤器 null 中的 LocaleResolver 仍显示它已 Autowiring ! Spring MVC 3.1.1/Spring 安全 3.1.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10301291/

相关文章:

java - Spring MockMvc 返回 200 而不是 201。如何调试?

java - spring Bean 创建异常 Error creating bean with name

iphone - 如何针对不同的语言本地化 iPhone 应用程序?

javascript - 将时区设置为 "' 时,IE 11 抛出 "Europe/London"timeZone' is outside of valid range"

spring - Spring+Hibernate配置中获取EntityManager

java - Catalina 生命周期异常

spring - JSF bean 和可序列化问题

ios - 如果我要本地化一个应用程序,我是否也应该本地化该应用程序的应用商店标题?

Java:MDB 和 Spring 的 SingletonBeanFactoryLocator

spring - 将 applicationContext 拆分为多个文件