SpringBoot项目实现国际化
原理:
核心是通过MessageSource接口,它根据当前用户的区域信息,从配置的资源文件(.properties)中加载对应的文本信息。
三个关键类:
LocaleResolver
Locale
MessageSource
LocaleResolver接口:其实现类有AcceptHeaderLocaleResolver、SessionLocaleResolver、CookieLocaleResolver等
AcceptHeaderLocaleResolver: 默认Resolver, 根据HTTP请求头的Accept-Language头信息来解析Locale。
SessionLocaleResolver:根据用户当前的会话中存储的Locale信息来解析。
Locale: Locale对象代表了某种语言。
SpringBoot中通过LocaleResolver解析
得到的Locale对象将决定应用程序在用户界面中显示哪种语言。
MessageSource: 是Spring Framework提供的国际化消息解析器接口,负责加载不同语言环境下的资源。通常使用ResourceBundleMessageSource
或ReloadableResourceBundleMessageSource来加载.properties文件,ReloadableResourceBundleMessageSource可以读取外部文件,使用file:格式。
实现:
@Configuration
public class HeaderLocaleResolver implements LocaleResolver {private static final String ACCEPT_LANGUAGE = "Accept-Language";@Overridepublic Locale resolveLocale(HttpServletRequest request) {String acceptLanguage = request.getHeader(ACCEPT_LANGUAGE);if (StringUtils.isEmpty(acceptLanguage)) {return new Locale(Locale.ENGLISH.getLanguage(), Locale.ENGLISH.getCountry());}String[] parts = acceptLanguage.split("-|_");if (parts.length == 2) {Locale locale = new Locale(parts[0], parts[1]);return locale;} else if (parts.length == 1) {Locale locale = new Locale(parts[0]);return locale;} else {throw new IllegalArgumentException("Invalid language tag: " + acceptLanguage);}}@Overridepublic void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {}
}
@Slf4j
@Configuration
public class I18nConfig implements WebMvcConfigurer {@Value("spring.messages.basename.linux")private String baseName4Linux;@Value("spring.messages.basename.win")private String baseName4Win;@Value("spring.messages.encoding")private String encoding;@PostConstructpublic void init() {log.info("I18nConfig initialized");}@Beanpublic MessageSource messageSource() {ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();//判断系统String baseName = System.getProperty("os.name").toLowerCase().contains("win") ? baseName4Win : baseName4Linux;source.setBasename(baseName);source.setDefaultEncoding(encoding);source.setCacheSeconds(60);return source;}@Bean("localeResolver")@Primarypublic LocalResolver headerLocaleResolver() {return new HeaderLocaleResolver();}/*@Bean("localeResolver")@Primarypublic LocalResolver sessionLocaleResolver() {SessionLocaleResolver slr = new SessionLocaleResolver();slr.setDefaultLocale(Locale.ENGLISH);slr.setDefaultTimeZone(TimeZone.getTimeZone("UTC"));return slr;}*/@Beanpublic LocaleChangeInterceptor localeChangeInterceptor() {LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();interceptor.setParamName("code");return interceptor;}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(localeChangeInterceptor());}}
//业务代码...@Autowired
private MessageSource messageSource;...String i18nMsg=
messageSource.getMessage("user.select.confirm",null,LocaleContextHolder.getLocale());...