【发布时间】:2012-01-18 16:24:05
【问题描述】:
我在这里的第一个问题,我会尽量具体。我对 Spring 很陌生,我正在尝试创建非常简单的预订系统(但这实际上并不重要)。重要的是我正在创建一些基本模板,然后我将用真实的网页填写这些模板。应用程序适用于休眠、mysql,我还设置了 i18n 和 spring security。问题是我无法更改我的语言环境。唯一有效的方法是更改默认值。 首先,我浏览了很多 Web,我发现将 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。我调试了它,似乎它不是为此目的而创建的(这就是我需要的)。
这取自 spring 示例“联系人”,但是在此示例中,我找不到任何实际针对更改语言的代码。效果是它根本不起作用。它总是试图将语言环境更改为我的默认语言环境。好消息是,如果在调试模式下我手动将语言环境设置更改为其他设置,它工作正常,所以我心中充满希望...... ;-)
然后我找到了其他方法 - 通过创建我们自己的过滤器。我所做的是将找到的示例(不要记住作者)与 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 后,它创建没有“国家”属性的区域设置(仅设置语言)。老实说,我不知道这是否有任何问题——也许不是。
2. 更严重的问题是它不起作用......我的意思是它在过滤器链中的正确位置(在安全链之前),它产生正确的语言环境并以与RequestContextFilter 完全相同的方式设置它...但它根本不起作用。
如果有人可以根据我给出的示例或任何其他示例让我知道如何使 i18n 与 spring-security 一起使用,我将非常高兴...
谢谢!
附加信息: 我做了一些实验,似乎请求中的 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);
我通过 locale 'l' 它根本不起作用。我的意思是即使你明确地改变了语言环境也不会改变。
另一方面,如果我通过那里将 Locale 'l2' 修改为德语(在调试模式下)它工作正常!
这意味着由于某种原因来自 request.getLocale() 的 Locale 实例在某种程度上受到了青睐,也许稍后在代码中发生了一些我不知道/不理解的事情......
请让我知道我应该如何将这个 i18n 与安全性一起使用,因为我已经到了必须承认我不知道发生了什么的地步......
-====-======-======--=======-====
最终解决方案/答案(但仍然没有什么疑问) 感谢拉尔夫,我设法解决了我的问题。以前我走错了方向,但 roo 生成的项目推动了我前进。 看来我一直以错误/不准确的方式添加拦截器(以前的代码):
<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 进行任何其他更改。
现在问题消失了,但我不确定发生了什么。根据我在第二个示例(有效的示例)中的理解,我将拦截器设为“全局”。但是为什么第一个示例中定义的拦截器不起作用?有什么提示吗?
再次感谢您的帮助! N.
【问题讨论】:
-
嗨..我试过你的拦截器配置,但它不起作用。我的语言环境在登录页面上没有改变。但是成功登录后它工作正常。在登录页面上,它仅适用于系统区域设置。
标签: spring spring-mvc localization internationalization spring-security