Nir*_*wan 6 spring localization spring-mvc spring-security internationalization
我在这里的第一个问题,我将尝试具体.我是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>
Run Code Online (Sandbox Code Playgroud)
我发现这个过滤器确实在安全过滤器之前处理过,但是它没有以一种形式解析请求:http://someserver.com/bla/home?locale=en.我调试了它,它似乎不是为了这个目的而创建的(这就是我需要的).这是从春季样本"联系人"中获取的,但在此示例中,我找不到任何实际上针对更改语言的代码.结果是它根本不起作用.它总是尝试将语言环境更改为我的默认语言环境.好消息是,如果在调试模式下,我手动将区域设置更改为其他一个,它工作得很好,所以我心里充满希望... ;-)
然后我找到了其他方法 - 通过创建我们自己的过滤器.我所做的是合并找到的例子(不要记住作者)以及如何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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,解析了请求参数区域设置并设置了区域设置.有两个问题:1.发送请求后,xxxxx?locale=en它创建没有"country"属性的Locale(仅设置语言).说实话,我不知道是否有任何问题 - 也许不是.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);
}
(...)
Run Code Online (Sandbox Code Playgroud)
如果对这个方法:LocaleContextHolder.setLocale(l, this.threadContextInheritable);
我传递语言环境'l'它根本不起作用.我的意思是即使你明确改变了语言环境也不会改变.另一方面,如果我通过Locale'l2'修改为德语(在调试模式下)它工作正常!
这意味着由于某种原因,Locale实例从request.getLocale()某种程度上受到青睐,也许稍后会在代码中发生一些我不知道/不理解的事情......
请让我知道我应该如何使用这个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>
Run Code Online (Sandbox Code Playgroud)
这样,拦截器由于某种原因从未被调用过.
将拦截器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>
Run Code Online (Sandbox Code Playgroud)
...它开始工作正常,没有对security/web.xml进行任何其他更改.
现在问题已经消失,但我不确定发生了什么.根据我在第二个例子(有效的那个)中的理解,我使拦截器"全局".但为什么在第一个例子中定义的拦截器不起作用?任何提示?
再次感谢您的帮助!N.
- 发送请求 xxxxx?locale=en 后,它会创建没有“国家/地区”属性的区域设置(仅设置语言)。
这是预期的行为。在java中存在某种层次结构。语言比国家更通用。
背后的想法是,您可以使用更常见的语言的文本,但可以使用国家特定文件中的某些单位(例如货币)。
@参见: 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>
Run Code Online (Sandbox Code Playgroud)
要查看此示例的运行情况,请使用该 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
Run Code Online (Sandbox Code Playgroud)
那么您必须只更改安全过滤器 intersept-url 模式,如我上面所示 ( applicationContext-security.xml)!
现在您有一个应用程序,用户可以通过应用程序中的本地更改拦截器(当用户登录时)以及当他未登录时(在登录页面中)更改其本地
| 归档时间: |
|
| 查看次数: |
10053 次 |
| 最近记录: |