Spring's messageResource implicitly localized from Session - not having to pass Locale reference
I'm wondering, what is the best way of having something like prototype of messageResource (could be singleton too I guess) created for each request and populated with request's Locale or Locale gotten from User object in the session. So that one doesn't have to pass Locales around, which is very inconvenient if you don't need to localize only validation messages but even exception messages etc. If you have 2 exception boundaries its problem. One then has to pass references to services or have some context that aggregates them and all is done at one place.
I already have ResourceBundleMessageSource extended because of other reasons, so it could have locale state, but I don't know what is the best approach to this problem.
SHORTER VERSION : when request is being passed to ha开发者_StackOverflow社区ndler, grab User or Locale from Session and get CustomMessageSource from context and populate it > have the same CustomMessageSource instance available in Controller already Localized
You don't have problems with MessageSource being automatically "localized" from session when request comes ?
All references within the app context would point to localized messageResource.
@Autowired private MessageSource resource;
You can vote up SPR-8555 for servlet environment and SPR-8558 for Portlet environment.
Right now there's no out of the box support for this but you could easily come up with a custom component that delegates Locale
resolution to a LocaleResolver
and delegates the resolution call to a MessageSource
in turn:
public class LocalizedMessageSource {
private final MessageSource messageSource;
private final LocaleResolver localeResolver;
public LocalizedMessageSource(MessageSource messageSource,
LocaleResolver localeResolver) {
Assert.notNull(messageSource);
Assert.notNull(localeResolver);
this.messageSource = messageSource;
this.localeResolver = localeResolver;
}
public String getMessage(MessageSourceResolvable resolvable) {
return messageSource.getMessage(resolvable, getLocale());
public String getMessage(String code, Object[] args) {
return messageSource.getMessage(code, args, getLocale());
getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
return messageSource.getMessage(code, args, defaultMessage, getLocale());
}
private Locale getLocale() {
return localeResolver.resolveLocale(getCurrentRequest());
}
private HttpServletRequest getCurrentRequest() {
return ((ServletRequestAttributes) RequestContextHolder
.currentRequestAttributes()).getRequest();
}
}
If you inject that component into your Spring MVC controller you can simply resolve messages without the Locale
piped through the controller method signature. I've opened a JIRA ticket to suggest an enhancement added to the Spring codebase.
精彩评论