在Spring Boot实现国际化的案例


将 I18N 添加到我们的 API 非常简单。因此,如果您正在考虑创建供全球使用的 API(并且如果您还没有这样做),那么将其添加到您的其他良好实践(干净的代码、文档、测试……)中并不是一个坏主意。
I18N国际化是设计软件应用程序的过程,以便它可以适应各种语言和地区,而无需进行工程更改。
整体流程
该过程包括四个步骤:

  1. 创建我们的消息服务
  2. 为我们想要支持的所有语言添加资源包
  3. 将变量添加到应用程序属性
  4. 开始使用我们的消息服务

1. 创建服务
让我们首先创建一个将用作消息服务的类。


@Service
public class MessageService {

    @Autowired
    private ResourceBundleMessageSource messageSource;

    @Value("${custom.app.locale}")
    private String systemLanguage;

    private Locale locale;

    @PostConstruct
    private void init() {
        locale = new Locale(systemLanguage);
        LocaleContextHolder.setDefaultLocale(locale);
    }

    public String getMessage(String prefix, String key){
        return getMessage(prefix, key,
"");
    }

    public String getMessage(String prefix, String key, String value){
        List<String> listOfValues = Collections.singletonList(value);
        return getMessage(prefix, key, listOfValues);
    }

    public String getMessage(String prefix, String key, List<String> args){
        return messageSource.getMessage(concatPrefixAndKey(prefix, key), args.toArray(), locale);
    }

    public String getMessage(String prefix, String key, List<String> args, Locale requestedLocale){
        if (requestedLocale == null){
            return getMessage(prefix, key, args);
        } else {
            return messageSource.getMessage(concatPrefixAndKey(prefix, key), args.toArray(), requestedLocale);
        }
    }

    public String getRequestLocalizedMessage(String prefix, String key){
        return getRequestLocalizedMessage(prefix, key, new ArrayList<>());
    }

    public String getRequestLocalizedMessage(String prefix, String key, List<String> args){
        return getMessage(prefix, key, args, LocaleContextHolder.getLocale());
    }

    private String concatPrefixAndKey(String prefix, String key){
        return prefix.concat(
".").concat(key);
    }
}

 
2.添加消息
现在,我们将在资源文件夹中创建一个资源包,并为我们想要支持的每种语言添加一个属性文件。
messages.properties
## GENERIC MESSAGES
generic.message.i18n=Hey, this is a message in english.

messages_en.properties
## GENERIC MESSAGES
generic.message.i18n=Hey, this is a message in english.

messages_es.properties
## GENERIC MESSAGES
generic.message.i18n=Hey, este es un mensaje en español.

messages_fr.properties
## GENERIC MESSAGES
generic.message.i18n=Salut, c'est un message en français.

 
3.更新application.properties
在这里,我们将添加两个变量,一个用于默认语言,一个用于应用程序编码。

# The default locale for our API
custom.app.locale=fr

# This sets the Spring boot encoding used for the API responses
spring.messages.encoding=ISO-8859-1

 
4.使用服务
最后一步,我们需要连接我们的消息服务并使用它。为此,我创建了一个调用getRequestLocalizedMessage方法的简单控制器。该方法使用LocalContextHolder来检测Accept-Language标头。如果标头存在,它将以请求的语言返回响应。如果不是,它会以默认语言返回消息。

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private MessageService messageService;

    private final String prefixKey =
"generic.message";

    @GetMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<String> getTest(){
        return ResponseEntity.status(HttpStatus.OK).body(messageService.getRequestLocalizedMessage(prefixKey,
"i18n"));
    }
}

您可以使用 MessageService 中的其他方法来实现相同的目标。
// You can pass the Locale as an argument to the getMessage function to get the message in a specific language

Locale requestedLocale = new Locale(
"es");
messageService.getMessage(prefixKey,
"i18n", new ArrayList<>(), requestedLocale);

// OR

// You can use the getMessage without a specific locale to get the message in the default language
messageService.getMessage(prefixKey,
"i18n");