Internationalization is mainly the introduction of Messagesource, we simply look at how to use, and its principle.
1.1 Setting Up resource files
Create a new i18n directory in properties
Create a new message file:
Messages.properties
error.title=Your request cannot be processed
Messages_zh_cn.properties
error.title=您的请求无法处理
1.2 Configuration
Modify the contents of the properties file: Configure Spring.message.basename in APPLICATION.YML or application.properties
spring: application: name: test-worklog messages: basename: i18n/messages encoding: UTF-8
1.3 Use
Refer to the Messagesource of automatic annotations, call it, and messageSource.getMessage
note that you need to LocaleContextHolder.getLocale()
get the current region by.
@Autowiredprivate MessageSource messageSource;/** * 国际化 * * @param result * @return */public String getMessage(String result, Object[] params) { String message = ""; try { Locale locale = LocaleContextHolder.getLocale(); message = messageSource.getMessage(result, params, locale); } catch (Exception e) { LOGGER.error("parse message error! ", e); } return message;}
How do I set up a personalized region? forLanguageTag
can be
Locale locale = Locale.forLanguageTag(user.getLangKey());
1.4 Principle Analysis
MessageSourceAutoConfiguration
, the AutoConfig is realized.
@Configuration@ConditionalOnMissingBean(value = MessageSource.class, search = SearchStrategy.CURRENT)@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)@Conditional(ResourceBundleCondition.class)@EnableConfigurationProperties@ConfigurationProperties(prefix = "spring.messages")public class MessageSourceAutoConfiguration {
This class reads the configuration file on the one hand, creating an instance of Messagesource:
@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); if (StringUtils.hasText(this.basename)) { messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray( StringUtils.trimAllWhitespace(this.basename))); } if (this.encoding != null) { messageSource.setDefaultEncoding(this.encoding.name()); } messageSource.setFallbackToSystemLocale(this.fallbackToSystemLocale); messageSource.setCacheSeconds(this.cacheSeconds); messageSource.setAlwaysUseMessageFormat(this.alwaysUseMessageFormat); return messageSource; }
Therefore, the default is loaded ResourceBundleMessageSource
, and the class is derived from the Abstractresourcebasedmessagesource
@Override public final String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { String msg = getMessageInternal(code, args, locale); if (msg != null) { return msg; } if (defaultMessage == null) { String fallback = getDefaultMessage(code); if (fallback != null) { return fallback; } } return renderDefaultMessage(defaultMessage, args, locale); }
Finally, call Resolvecode to get the message and get the message through ResourceBundle.
@Override protected Messageformat Resolvecode (String code, locale locale) {//Traverse language file path set<string > basenames = Getbasenameset (); for (String basename:basenames) {ResourceBundle bundle = Getresourcebundle (basename, locale); if (bundle = null) {Messageformat Messageformat = Getmessageformat (Bundle, code, locale); if (Messageformat! = null) {return messageformat; }}} return null; }//Get ResourceBundle protected ResourceBundle getresourcebundle (String basename, locale locale) {if (Getcachem Illis () >= 0) {//Fresh Resourcebundle.getbundle call in order to let ResourceBundle//does its n ative caching, at the expense for more extensive lookup steps. Return Dogetbundle (basename, locale); } else {//cache Forever:prefer locale cache over repeated getbundle calls. Synchronized (this.cachedresourcebundles) {map<locale, resourcebundle> localemap = this.cached Resourcebundles.get (basename); if (localemap! = null) {ResourceBundle bundle = localemap.get (locale); if (bundle! = null) {return bundle; }} try {ResourceBundle bundle = Dogetbundle (basename, locale); if (Localemap = = null) {Localemap = new Hashmap<locale, resourcebundle> (); This.cachedResourceBundles.put (basename, Localemap); } localemap.put (locale, bundle); return bundle; } catch (MissingResourceException ex) {if (logger.iswarnenabled ()) { Logger.warn ("ResourceBundle [" + basename + "] not found for Messagesource:" + ex. GetMessage ()); }//Assume bundle not found//-do not throw-the exception to allow for Checki NG parent Message source. return null; }}}}//ResourceBundle protected ResourceBundle dogetbundle (String basename, locale locale) throw S missingresourceexception {return resourcebundle.getbundle (basename, Locale, Getbundleclassloader (), New MessageS Ourcecontrol ());}
Last look at Getmessageformat:
/** * Return A Messageformat for the given bundle and code, * fetching already generated messageformats from the C Ache. * @param bundle the ResourceBundle to work in * @param code the message code to retrieve * @param locale the Local E to use to build the Messageformat * @return The resulting messageformat, or {@code null} if no message * defined For the given code * @throws missingresourceexception if thrown by the ResourceBundle */protected Messageform At Getmessageformat (resourcebundle bundle, String code, locale locale) throws MissingResourceException { Synchronized (this.cachedbundlemessageformats) {//read from cache map<string, Map<locale, Messageform At>> CodeMap = This.cachedBundleMessageFormats.get (bundle); Map<locale, messageformat> localemap = null; if (CodeMap! = null) {Localemap = Codemap.get (code); if (localemap! = null) { Messageformat result = localemap.get (locale); if (result! = NULL) {return result; }}}//Cache miss, read String msg = getstringornull (bundle, code) from bundle; if (msg! = null) {if (CodeMap = = null) {CodeMap = new hashmap<string, MAP&L T Locale, messageformat>> (); This.cachedBundleMessageFormats.put (bundle, CodeMap); } if (Localemap = = null) {Localemap = new Hashmap<locale, messageformat> (); Codemap.put (code, LOCALEMAP); } Messageformat result = Createmessageformat (msg, locale); Localemap.put (locale, result); return result; } return null; } }
Jadepeng
Source: Jqpeng's technical notepad--http://www.cnblogs.com/xiaoqi
Your support is the greatest encouragement to bloggers, thank you for your serious reading.
The copyright of this article is owned by the author, welcome to reprint, but without the consent of the author must retain this paragraph, and in the article page obvious location to the original link, otherwise reserves the right to pursue legal responsibility.
Spring Boot Internationalization