- github: https://github.com/hi-cooper/cz-tutorials/tree/main/i18n-demo
- 采用java.text.MessageFormat来格式化。如
MessageFormat.format("简体中文{0}, {1}", new String[] {"参数A", "参数B"});
1 默认properties方式
SHA1: 9ac4ad7e2e0b4a50db46326280dd1c1cfdad6b4a
1.1. yml
server:
port: 8888
spring:
web:
locale: zh_CN # 设置本地语言为zh_CN
messages:
basename: i18n/messages # 在i18n文件下message开头的配置文件
cache-duration: 10 # 配置缓存的时间,单位 s
encoding: UTF-8 # 编码格式
1.2 自定义解析类CustomLocaleResolver
package com.taiwii.i18ndemo.config;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
/**
* 自定义Locale header key为HEADER_LOCALE,值为zh_CN、en_US
*/
@Slf4j
@Component("localeResolver")
public class CustomLocaleResolver extends AcceptHeaderLocaleResolver {
public final static String HEADER_LOCALE = "language";
private static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
private static final List SUPPORTED_LOCALES = Arrays.asList(Locale.US, Locale.SIMPLIFIED_CHINESE);
public CustomLocaleResolver() {
setDefaultLocale(DEFAULT_LOCALE);
setSupportedLocales(SUPPORTED_LOCALES);
}
@Override
public Locale resolveLocale(HttpServletRequest request) {
String lang = request.getHeader(HEADER_LOCALE);
return getLocale(lang);
}
private Locale getLocale(String lang) {
if (StringUtils.isEmpty(lang)) {
return getDefaultLocale();
}
try {
String[] items = lang.split("_");
if (items.length != 2) {
return getDefaultLocale();
}
return new Locale(items[0], items[1]);
} catch (Exception e) {
log.error(e.getMessage(), e);
return getDefaultLocale();
}
}
}
1.3 WebConfig
package com.taiwii.i18ndemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 默认的拦截器,其中language表示要切换语言的参数名
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
localeInterceptor.setParamName(CustomLocaleResolver.HEADER_LOCALE);
registry.addInterceptor(localeInterceptor);
}
}
1.4 I18nHelper
package com.taiwii.i18ndemo.helper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import java.util.Locale;
@Slf4j
@Component
public class I18nHelper {
private static MessageSource messageSource;
public I18nHelper(MessageSource messageSource) {
I18nHelper.messageSource = messageSource;
}
public static String getMessage(Locale locale, String key, Object... args) {
String message = null;
try {
message = messageSource.getMessage(key, args, locale);
} catch (Exception e) {
log.error(e.getMessage(), e);
message = key;
}
return message;
}
public static String getMessage(String key, Object... args) {
return getMessage(LocaleContextHolder.getLocale(), key, args);
}
}
1.5 Controller
package com.taiwii.i18ndemo.controller;
import com.taiwii.i18ndemo.helper.I18nHelper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v1/language")
public class LanguageController {
@GetMapping("/test")
public String test() {
return I18nHelper.getMessage("language.zh_cn");
}
@GetMapping("/test2")
public String test2() {
return I18nHelper.getMessage("language.zh_cn", new String[] {"参数A", "参数B"});
}
}
1.6 资源文件
- /resources/i18n/messages_en_US.properties
language.zh_cn=Chinese{0}, {1}
language.en_us=US
- /resources/i18n/messages_zh_CN.properties
language.zh_cn=简体中文{0}, {1}
language.en_us=英语(美国)
1.7 测试
# 请求
curl -X GET localhost:8888/v1/language/test --header "language: zh_CN"
# 返回
简体中文
# 请求
curl -X GET localhost:8888/v1/language/test --header "language: en_US"
# 返回
Chinese
# 请求
curl -X GET localhost:8888/v1/language/test2 --header "language: zh_CN"
# 返回
简体中文参数A, 参数B
# 请求
curl -X GET localhost:8888/v1/language/test2 --header "language: en_US"
# 返回
Chinese参数A, 参数B
2 自定义MessageSource
- brahche:i18n-自定义MessageSource
- 代码基于第1章节
- 测试结果与1.6相同
2.1 yml
仅保留以下内容:
server:
port: 8080
2.1 删除资源文件夹
删除1.6创建的资源文件夹。即/resources/i18n
2.3 自定义MessageSource
为简单起见,这里采用将资源存储于内存的实现方式,其他实现方式可自行扩展。
package com.taiwii.i18ndemo.config;
import org.springframework.context.support.AbstractMessageSource;
import org.springframework.stereotype.Component;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@Component("messageSource")
public class MemoryMessageSource extends AbstractMessageSource {
private static final Map<String, String> MESSAGES = new HashMap<>();
private static final Map<String, String> EN_CN = new HashMap<>();
static {
MESSAGES.put("en_US:language.zh_cn", "Chinese{0}, {1}");
MESSAGES.put("en_US:language.en_us", "US");
MESSAGES.put("zh_CN:language.zh_cn", "简体中文{0}, {1}");
MESSAGES.put("zh_CN:language.en_us", "英语(美国)");
}
@Override
protected MessageFormat resolveCode(String code, Locale locale) {
String message = MESSAGES.get(String.format("%s_%s:%s", locale.getLanguage(), locale.getCountry(), code));
return new MessageFormat(message, locale);
}
}