我在这里的第一个问题,我将尝试具体。我对Spring很陌生,我试图创建一个非常简单的预订系统(但这实际上并不重要)。重要的是我正在创建一些基本模板,然后我将通过真实的网页填写。应用程序适用于hibernate,mysql,我还设置了i18n和spring security。问题在于我无法改变我的语言环境。唯一有效的是改变默认值。 首先,我浏览了Web A LOT,我发现使用i18n和弹簧安全性通常更复杂。我发现的是我需要额外的过滤器:
<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
。我调试了它,它似乎不是为了这个目的而创建的(这就是我需要的)。
这取自春季样本&#34;联系人&#34;但是在这个例子中,我找不到任何实际上以改变语言为目标的代码。效果是它根本不起作用。它总是尝试将语言环境更改为我的默认语言环境。好消息是,如果在调试模式下,我手动将区域设置更改为其他一个,它工作得很好,所以我心里充满希望......; - )
然后我通过创建我们自己的过滤器找到了其他方法。我所做的是合并找到的例子(不要记得作者)以及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();
}
}
}
如您所见,解析了请求参数区域设置并设置了区域设置。有两个问题:
1.发送请求xxxxx?locale=en
后,它会创建没有&#34; country&#34;的区域设置。属性(仅设置语言)。说实话,我不知道它是否有任何问题 - 也许不是。
2.更严重的问题是它不起作用......我的意思是它在过滤器链中的正确位置(在安全性之前),它产生正确的区域设置并且将它设置为exackly像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);
我通过现场直播&#39; l&#39;它根本不起作用。我的意思是即使你明确改变了语言环境也没有改变。
另一方面,如果我通过Locale&#39; l2&#39;修改为德语(在调试模式下)它工作正常!
这意味着由于某种原因,来自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进行任何其他更改。
现在问题已经消失,但我不确定发生了什么。根据我在第二个例子(有效的那个)中的理解,我制作了拦截器&#34; global&#34;。但是为什么在第一个例子中定义的拦截器不起作用?任何提示?
再次感谢您的帮助! Ñ
答案 0 :(得分:1)
- 发送请求xxxxx?locale = en后,它会创建没有“country”属性的Locale(仅设置语言)。
醇>
这是预期的行为。在java中有某种层次结构。 语言比国家更普遍。
背后的想法是,你可以在更常见的语言中使用文本,但在国家特定文件中有一些单位(如货币)。
@see:http://java.sun.com/developer/technicalArticles/Intl/IntlIntro/
- 更严重的问题是它不起作用......
醇>
它应该在没有任何手工实现的情况下工作!
您需要注册Local Change Interceptor,并需要为登录页面设置permitAll。
<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>
要查看此示例正在运行,请使用该roo脚本创建一个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
然后你必须只改变安全过滤器intersept-url模式,如上所示(applicationContext-security.xml
)!
现在你有一个应用程序,用户可以通过应用程序中的本地更改拦截器(当用户登录时)以及未登录时(在登录页面中)更改其本地
答案 1 :(得分:0)
当我使用GWT应用程序时,我遇到了与Localization类似的问题。我注意到的问题是,当我们映射
时<filter-mapping>
<filter-name>localizationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
到过滤器,偶数图像请求被路由到过滤器。这些请求有时会遗漏locale参数,因此当多个请求命中过滤器时,Locale参数不会。因此,只要我收到locale参数,就会将其放入会话中。记录所有请求标头和值,您可能会找到根本原因。