26 октября 2022
Тэги: gradle, Kotlin, rest, Spring Boot, руководство, файлы.
При разработке приложения, ориентированного на мировой рынок, сразу следует закладывать поддержку нескольких языков. Добавление новой локализации должно выполняться быстро и при этом не требовать значительного рефакторинга. К счастью, если вы разрабатываете приложение на Spring Boot, то реализовать такую поддержку довольно просто.
В качестве примера с помощью Spring Initializr создадим заготовку gradle-проекта на Kotlin и добавим всего 1 зависимость: spring-boot-starter-web. Наше приложение будет в зависимости от переданной локали возвращать текст на соответствующем языке.
Пример приложения также доступен на github.
Суть локализации сводится к тому, что все тексты мы держим в отдельных property-файлах, а для каждого текстового фрагмента используем специальный код.
В проекте в папке resources создадим три файла. Первый назовём messages.properties. Это файл с локализацией по умолчанию, т.е. он будет использоваться, когда локаль не передана в явном виде.
В данном случае мы сделали локализацию текста с кодом text.welcome.
Далее создадим локализацию для английского языка в файле messages_en.properties:
Ну и, наконец, создадим локализацию для русского языка в файле messages_ru.properties:
Эта группа из трёх файлов называется Resource Bundle.
Важно! Чтобы у вас корректно обрабатывался текст с кириллицей, убедитесь, что этот property-файл имеет кодировку utf-8! Если это не так – настройте вашу IDE соответствующим образом. В IntelliJ Idea это настраивается в Settings – File Encodings – раздел Properties Files.
Теперь создадим спринговую конфигурацию, которую назовём MessageConfig:
В этой конфигурации определим два бина.
Бин localeResolver задаёт локаль, которая будет использоваться в том случае, если она не задана явно. В данном случае это Locale.US. Чтобы не создавать лишних переменных, для инициализации используем котлиновскую функцию with().
Второй бин называется messageSource, типизированный классом ResourceBundleMessageSource. Он определяет источник локализаций для различных локалей, т.е. группу property-файлов, которые мы создали выше. Метод setUseCodeAsDefaultMessage() определяет, что, если по коду не удалось найти даже дефолтной реализации, то в качестве текста возвращать сам этот код, а не кидать исключение.
Метод setBasenames() устанавливает общий префикс имени всех файлов с локализациями. В нашем случае это «messages». Ну и в конце задаём кодировку файлов с помощью setDefaultEncoding().
Ну а теперь нам осталось создать простенький rest-контроллер с GET-методом, который будет возвращать текстовую строку в зависимости от локали, переданной этому методу в качестве параметра.
Данный контроллер мы связываем с урлом /messages и подставляем в него компонент MessageSource, который и обеспечит нам функционал локализации.
Далее внутри контроллера определяем следующий GET-метод:
Единственным параметром тут является локаль, которая передаётся в HTTP-заголовке Accept-Language (аннотация @RequestHeader). Причём этот параметр является необязательным (required = false), а потому по умолчанию равен null.
Все имена стандартных заголовков содержатся в спринговом классе HttpHeaders.
В самом методе вызываем getMessage(), в который передаём код текста (text.welcome) и локаль. Причём если локаль не передали, будем подставлять Locale.US благодаря элвис-оператору.
Теперь запускаем приложение и выполняем GET-запрос на эндпоинт /messages. Если мы не передаём заголовок Accept-Language, то в ответе увидим строку на английском.
Если же в этом заголовке передать значение «ru», то увидим текст на русском.
Таким образом, вы можете добавлять сколько угодно локализаций. Просто создайте новый property-файл с названием нужной вам локали.
Благодаря этому простому примеру мы убедились, что создать мультиязычное приложение на Spring Boot не составляет труда. Локализация сводится к добавлению нужного текстового файла без изменения кода. Всю работу с локалями берёт на себя компонент MessageSource.
Напоследок хочу заметить, что, в зависимости от требований, локаль может определяться не параметром запроса (как в нашем случае), а настройками самого сервера.
Kotlin, Java, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Linux, Hibernate, Collections, Stream API, многопоточность, файлы, Nginx, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.