Spring Security版本:2.0.5 

取出Spring Security的异常信息 

Java代码  收藏代码
  1. ${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message}  


异常信息已经经过国际化处理,所以只要直接取出异常的message属性即可。 
如在org.springframework.security.providers.dao.AbstractUserDetailsAuthenticationProvider.authenticate(Authentication)中: 

Java代码  收藏代码
  1. ...  
  2.             try {  
  3.                 user = retrieveUser(username,(UsernamePasswordAuthenticationToken) authentication);  
  4.             } catch (UsernameNotFoundException notFound) {  
  5.                 if (hideUserNotFoundExceptions) {  
  6.                     throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));  
  7.                 } else {  
  8.                     throw notFound;  
  9.                 }  
  10.             }  
  11. ...  



Java代码  收藏代码
  1. messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials")  



org.springframework.context.support.MessageSourceAccessor 

Java代码  收藏代码
  1. protected Locale getDefaultLocale() {  
  2.     return (this.defaultLocale != null ? this.defaultLocale : LocaleContextHolder.getLocale());  
  3. }  
  4.   
  5. public String getMessage(String code, String defaultMessage) {  
  6.     return this.messageSource.getMessage(code, null, defaultMessage, getDefaultLocale());  
  7. }  



org.springframework.context.i18n.LocaleContextHolder 

Java代码  收藏代码
  1. public static Locale getLocale() {  
  2.     LocaleContext localeContext = getLocaleContext();  
  3.     return (localeContext != null ? localeContext.getLocale() : Locale.getDefault());  
  4. }  
  5.   
  6. public static LocaleContext getLocaleContext() {  
  7.     LocaleContext localeContext = (LocaleContext) localeContextHolder.get();  
  8.     if (localeContext == null) {  
  9.         localeContext = (LocaleContext) inheritableLocaleContextHolder.get();  
  10.     }  
  11.     return localeContext;  
  12. }  



可知保存Local信息的localeContext是从线程变量localeContextHolder中取出来的,从而可以知道必须先在localeContextHolder中设置好localeContext,国际化才能正确工作。 

Spring框架中有一个过滤器是负责这个工作的,它就是org.springframework.web.filter.RequestContextFilter。 

在web.xml中定义RequestContextFilter,注意要定义在springSecurityFilterChain前面才能正确工作。 

Xml代码  收藏代码
  1. <filter>  
  2.     <filter-name>localizationFilter</filter-name>  
  3.     <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>  
  4. </filter>  
  5.   
  6. <filter-mapping>  
  7.     <filter-name>localizationFilter</filter-name>  
  8.     <url-pattern>/*</url-pattern>  
  9. </filter-mapping>  



Java代码  收藏代码
  1. /** 
  2.  * Servlet 2.3 Filter that exposes the request to the current thread, 
  3.  * through both {@link org.springframework.context.i18n.LocaleContextHolder} and 
  4.  * {@link RequestContextHolder}. To be registered as filter in <code>web.xml</code>. 
  5.  * 
  6.  * <p>Alternatively, Spring's {@link org.springframework.web.context.request.RequestContextListener} 
  7.  * and Spring's {@link org.springframework.web.servlet.DispatcherServlet} also expose 
  8.  * the same request context to the current thread. 
  9.  * 
  10.  * <p>This filter is mainly for use with third-party servlets, e.g. the JSF FacesServlet. 
  11.  * Within Spring's own web support, DispatcherServlet's processing is perfectly sufficient. 
  12.  * 
  13.  * @author Juergen Hoeller 
  14.  * @author Rod Johnson 
  15.  * @since 2.0 
  16.  * @see org.springframework.context.i18n.LocaleContextHolder 
  17.  * @see org.springframework.web.context.request.RequestContextHolder 
  18.  * @see org.springframework.web.context.request.RequestContextListener 
  19.  * @see org.springframework.web.servlet.DispatcherServlet 
  20.  */  


由RequestContextFilter的注释可知它主要用于third-party servlets,Spring MVC正常是不需要使用的,由此可知Spring Security与Spring MVC配合得不太完美。