Back to Javatutorial

SpringMVC中的国际化功能

docs/Spring全家桶/SpringMVC/SpringMVC中的国际化功能.md

1.0.06.5 KB
Original Source

ʻ


ڿӦóʱ򣬾ֶ֧Եֶ֧ԵĹ֮ܳΪʻӢinternationalizationдΪi18nΪĸiĩĸnм18ĸ

ضıػܣӢlocalizationдΪL10nػָݵڵʾȡ

ҲаߺϳΪȫ򻯣ӢglobalizationдΪg11n

JavaУֶ֧ԺͱػͨMessageFormat``Localeʵֵģ

WebӦóҪʵֹʻܣҪȾViewʱҪѸԵԴļͬûͬһҳʱʾԾDzͬġ

Spring MVCӦóʵֹʻ

ȡLocale

ʵֹʻĵһǻȡûLocaleWebӦóУHTTP淶涨ЯAccept-Languageͷָʾû趨˳磺

Accept-Language: zh-CN,zh;q=0.8,en;q=0.2  
  

HTTPͷʾѡģѡģѡӢġqʾȨأǿɻһȼбתΪJavaLocaleûLocaleֻͨȨߵLocale

Spring MVCͨLocaleResolverԶHttpServletRequestлȡLocaleжLocaleResolverʵ࣬õCookieLocaleResolver

@Primary  
@Bean  
LocaleResolver createLocaleResolver() {  
    var clr = new CookieLocaleResolver();    clr.setDefaultLocale(Locale.ENGLISH);    clr.setDefaultTimeZone(TimeZone.getDefault());    return clr;}  
  

CookieLocaleResolver``HttpServletRequestлȡLocaleʱȸһضCookieжǷָLocaleûУʹHTTPͷȡûУͷĬϵLocale

ûһηվʱCookieLocaleResolverֻܴHTTPͷȡLocaleʹĬԡͨվҲûԼѡԣʱCookieLocaleResolverͻûѡԴŵCookieУһηʱͻ᷵ûϴѡԶĬԡ

ȡԴļ

ڶǰдģеַԴļķʽ洢ⲿڶԣļΪmessagesôԴļ밴·ʽclasspathУ

  • ĬԣļΪmessages.properties
  • ģLocalezh_CNļΪmessages_zh_CN.properties
  • ģLocaleja_JPļΪmessages_ja_JP.properties
  • ԡ

ÿԴļͬkey磬ĬӢģļmessages.properties£

language.select=Language  
home=Home  
signin=Sign In  
copyright=Copyright?{0,number,#}  
  

ļmessages_zh_CN.properties£

language.select=  
home=ҳ  
signin=¼  
copyright=Ȩ?{0,number,#}  
  

MessageSource

ǴһSpringṩMessageSourceʵԶȡе.propertiesļṩһͳһӿʵ֡롱

// code, arguments, locale:  
String text = messageSource.getMessage("signin", null, locale);  
  

Уsignin``.propertiesļжkeyڶObject[]ΪʽʱIJһǻȡûLocaleʵ

MessageSource£

@Bean("i18n")  
MessageSource createMessageSource() {  
    var messageSource = new ResourceBundleMessageSource();    // ָļUTF-8:  
    messageSource.setDefaultEncoding("UTF-8");    // ָļ:  
    messageSource.setBasename("messages");    return messageSource;}  
  

ע⵽ResourceBundleMessageSourceԶļԶԵԴļ

ע⵽SpringᴴֻһMessageSourceʵԼMessageSourceרŸҳʻʹõģΪi18n``MessageSourceʵͻ

ʵֶ

ҪViewʹMessageSource``LocaleԣͨдһMvcInterceptorԴע뵽ModelAndViewУ

@Component  
public class MvcInterceptor implements HandlerInterceptor {  
    @Autowired    LocaleResolver localeResolver;  
    // עעMessageSourcei18n:  
    @Autowired    @Qualifier("i18n")    MessageSource messageSource;  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {        if (modelAndView != null) {            // ûLocale:  
            Locale locale = localeResolver.resolveLocale(request);            // Model:  
            modelAndView.addObject("__messageSource__", messageSource);            modelAndView.addObject("__locale__", locale);        }    }}  
  

ҪWebMvcConfigurerעMvcInterceptorڣͿViewеMessageSource.getMessage()ʵֶԣ

{{ __messageSource__.getMessage('signin', null, __locale__) }}  
  

дȻУʽ̫ˡʹViewʱҪÿضView涨ƹʻPebbleУǿԷװһʻƾ»_һ´ViewResolverĴ룺

@Bean  
ViewResolver createViewResolver(@Autowired ServletContext servletContext, @Autowired @Qualifier("i18n") MessageSource messageSource) {  
    var engine = new PebbleEngine.Builder()            .autoEscaping(true)            .cacheActive(false)            .loader(new Servlet5Loader(servletContext))            // չ:  
            .extension(createExtension(messageSource))            .build();    var viewResolver = new PebbleViewResolver();    viewResolver.setPrefix("/WEB-INF/templates/");    viewResolver.setSuffix("");    viewResolver.setPebbleEngine(engine);    return viewResolver;}  
  
private Extension createExtension(MessageSource messageSource) {  
    return new AbstractExtension() {        @Override        public Map<String, Function> getFunctions() {            return Map.of("_", new Function() {                public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {                    String key = (String) args.get("0");                    List<Object> arguments = this.extractArguments(args);                    Locale locale = (Locale) context.getVariable("__locale__");                    return messageSource.getMessage(key, arguments.toArray(), "???" + key + "???", locale);                }                private List<Object> extractArguments(Map<String, Object> args) {                    int i = 1;                    List<Object> arguments = new ArrayList<>();                    while (args.containsKey(String.valueOf(i))) {                        Object param = args.get(String.valueOf(i));                        arguments.add(param);                        i++;                    }                    return arguments;                }                public List<String> getArgumentNames() {                    return null;                }            });        }    };}  
  

ǿ԰ѶҳдΪ

{{ _('signin') }}  
  

ǴĶԣҪѲȥ

<h5>{{ _('copyright', 2020) }}</h5>  
  

ʹViewʱҲӦӿʵָ﷨

лLocale

ҪûֶлLocaleдһLocaleControllerʵָùܣ

@Controller  
public class LocaleController {  
    final Logger logger = LoggerFactory.getLogger(getClass());  
    @Autowired    LocaleResolver localeResolver;  
    @GetMapping("/locale/{lo}")    public String setLocale(@PathVariable("lo") String lo, HttpServletRequest request, HttpServletResponse response) {        // ݴloLocaleʵ:  
        Locale locale = null;        int pos = lo.indexOf('_');        if (pos > 0) {            String lang = lo.substring(0, pos);            String country = lo.substring(pos + 1);            locale = new Locale(lang, country);        } else {            locale = new Locale(lo);        }        // 趨Locale:  
        localeResolver.setLocale(request, response, locale);        logger.info("locale is set to {}.", locale);        // ˢҳ:  
        String referer = request.getHeader("Referer");        return "redirect:" + (referer == null ? "/" : referer);    }}  
  

ҳУͨϽǸûṩһѡбЧ

лģ

С

֧ҪHTTPнûLocaleȻԲͬLocaleʾͬԣ

Spring MVCӦóͨMessageSource``LocaleResolverViewʵֹʻ