我需要在成功验证后更改区域设置。
和LocaleResolver:
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lng" />
</bean>
<bean id="localeResolver"
class="web.MyLocaleResolver">
</bean>
public class MyLocaleResolver extends AbstractLocaleResolver {
private Locale default = Locale.ENGLISH;
@Override
public Locale resolveLocale(HttpServletRequest hsr) {
return this.default;
}
@Override
public void setLocale(HttpServletRequest hsr, HttpServletResponse hsr1, Locale default) {
this.default = default;
}
}
安全性:
<form-login login-page="/login"
authentication-success-handler- ref="MySuccessAuthHandler"/>
<beans:bean id="MySuccessAuthHandler" class="web.MySuccessfulAuthenticationHandler">
<beans:property name="defaultTargetUrl" value="/index.htm"></beans:property>
</beans:bean>
public class MySuccessfulAuthenticationHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
super.onAuthenticationSuccess(request, response, authentication);
RequestContextUtils.getLocaleResolver(request).setLocale(request, response, Locale.ENGLISH);
}
}
当我尝试按RequestContextUtils
设置区域设置时,我得到NullPointer异常。
答案 0 :(得分:9)
LocaleResolver
在请求上下文中由DispatcherServlet
公开,而AuthenticationSuccessHandler
在请求输入DispatcherServlet
之前被触发(实际上,被解雇的请求SavedRequestAwareAuthenticationSuccessHandler
永远不会进入{ {1}},因为此处理程序执行重定向。)
因此,在这种情况下,您无法通过DispatcherServlet
访问LocaleResolver
。您可以尝试明确地将RequestContextUtils
注入LocaleResolver
,例如,使用自动装配。
答案 1 :(得分:2)
尽管在使用Spring Security时通常无法访问DispatcherServlet,但您可以在安全过滤器链之前添加RequestContextFilter,它会公开所有请求属性,例如localeResolver。
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
即使这应该让你的例子有用。对于其他人:另一种选择是使用WebApplicationContextUtils.getWebApplicationContext(ServletContext)
传递HttpServletRequest中可用的ServletContext
答案 2 :(得分:1)
Kafkaesque的解决方案尚未完成。
但即使是Spring安全文档也是错误的:
需要将LocaleContextHolder设置为包含正确的 调用过滤器之前的区域设置。你可以这样做 过滤自己(必须在Spring Security过滤器之前) web.xml)或者您可以使用Spring的RequestContextFilter。
您无法使用RequestContextFilter
,因为此过滤器不知道您的applicationContext中的任何LocaleResolver
。它只使用request.getLocale()
中的Accept-Language
标题的区域设置。
如果您想在此过滤器中使用自己的LocaleResolver,则需要自己编写:
@Component
public class LocaleRequestContextFilter extends OncePerRequestFilter
{
// basiert auf RequestContextFilter
@Inject
private LocaleResolver localeResolver;
@Override
protected void doFilterInternal ( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain ) throws ServletException, IOException
{
ServletRequestAttributes attributes = new ServletRequestAttributes(request, response);
initContextHolders(request, attributes);
try
{
filterChain.doFilter(request, response);
}
finally
{
resetContextHolders();
attributes.requestCompleted();
}
}
private void initContextHolders ( HttpServletRequest request, ServletRequestAttributes requestAttributes )
{
LocaleContextHolder.setLocaleContext(buildLocaleContext(request));
RequestContextHolder.setRequestAttributes(requestAttributes, false);
}
private LocaleContext buildLocaleContext ( final HttpServletRequest request )
{
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, localeResolver);
if (this.localeResolver instanceof LocaleContextResolver)
{
return ( (LocaleContextResolver) this.localeResolver ).resolveLocaleContext(request);
}
else
{
return new LocaleContext()
{
@Override
public Locale getLocale ( )
{
return localeResolver.resolveLocale(request);
}
};
}
}
private void resetContextHolders ( )
{
LocaleContextHolder.resetLocaleContext();
RequestContextHolder.resetRequestAttributes();
}
}
然后配置您的web.xml
<filter>
<filter-name>localeRequestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>localeRequestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>