Локалізація в IT — це як перекладач на конференції: користувачі говорять різними мовами, а система має відповідати їм зрозуміло. Уяви, що ти розробляєш додаток, який виходить на світовий ринок. Для користувачів з різних країн важливо, щоб інтерфейс, помилки і сповіщення були адаптовані під їхню мову та культурні особливості.
Що локалізуємо?
- Повідомлення про помилки: наприклад, замість сухого
must not be null, користувач із Росії має бачити:Поле не може бути порожнім. - Валідаційні повідомлення: коли форма заповнена неправильно, тексти попереджень теж мають бути мовою користувача.
- Інші сповіщення: інформація про некоректний ввід дат, чисел, email-ів тощо.
Як працює локалізація в Spring?
Spring дає потужний інструмент для локалізації — MessageSource. Це компонент, який відповідає за роботу з текстами і підтримує множинні мовні файли.
Компоненти локалізації
- Мовні файли: це звичайні
.propertiesфайли з ключами і їхніми значеннями, наприклад:messages_en.propertiesдля англійської.messages_ru.propertiesдля російської.
- MessageSource: Bean, який шукає потрібний файл залежно від поточної локалі.
- LocaleResolver: визначає, яка локаль активна для поточного користувача.
Налаштування локалізації в Spring-додатку
1. Підключення бібліотеки
Для початку переконайся, що в тебе підключені залежності web і валідації в pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2. Додаємо мовні файли
Створи в папці src/main/resources файли:
messages_en.properties:field.required=Field is required field.length=Field must not exceed {0} charactersmessages_ru.properties:field.required=Поле обов'язкове для заповнення field.length=Поле не повинне перевищувати {0} символів
Ці файли містять ключі і переклади. Ключі — це унікальні ідентифікатори повідомлень, а значення — тексти відповідною мовою.
3. Конфігурація MessageSource
У Spring Boot MessageSource налаштовується через Bean у конфігураційному класі. Додаємо наступний код:
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
@Configuration
public class LocalizationConfig {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}
Це говорить Spring шукати файли messages_*.properties в папці ресурсів.
4. Налаштування LocaleResolver
Додаємо LocaleResolver, щоб визначити мову користувача. Наприклад, можна використовувати Cookie для збереження вибору мови:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import java.util.Locale;
@Configuration
public class LocaleConfig {
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(Locale.ENGLISH); // Мова за замовчуванням
return localeResolver;
}
}
5. Перемикання локалі через контролер
Тепер створимо контролер, щоб користувачі могли змінювати мову. Наприклад, через параметр lang:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
@RestController
public class LanguageController {
private final LocaleResolver localeResolver;
public LanguageController(LocaleResolver localeResolver) {
this.localeResolver = localeResolver;
}
@GetMapping("/change-language")
public String changeLanguage(@RequestParam String lang, HttpServletRequest request, HttpServletResponse response) {
Locale locale = new Locale(lang);
localeResolver.setLocale(request, response, locale);
return "Language changed to " + lang;
}
}
Тепер запити виду /change-language?lang=ru будуть перемикати мову.
Локалізація повідомлень про помилки
Локалізуємо повідомлення від Bean Validation API.
1. Анотуємо поля DTO
Наш UserDTO може виглядати так:
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
public class UserDTO {
@NotNull(message = "{field.required}")
private String username;
@Size(max = 20, message = "{field.length}")
private String password;
// Геттери та сеттери
}
Ключі повідомлень про помилки (field.required і field.length) беруться з мовних файлів.
2. Приклад обробки в контролері
Створимо REST контролер, який обробляє POST-запит для реєстрації.
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public String createUser(@RequestBody @Valid UserDTO userDTO) {
return "User created: " + userDTO.getUsername();
}
}
Spring автоматично валідовує запити, а при помилці кидає виключення MethodArgumentNotValidException.
Локалізація помилок через GlobalExceptionHandler
Попередні лекції вчили нас використовувати @ControllerAdvice для глобальної обробки помилок. Локалізуємо помилки для користувачів:
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
private final MessageSource messageSource;
public GlobalExceptionHandler(MessageSource messageSource) {
this.messageSource = messageSource;
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex, Locale locale) {
Map<String, String> errors = new HashMap<>();
for (FieldError error : ex.getBindingResult().getFieldErrors()) {
String localizedErrorMessage = messageSource.getMessage(error, locale);
errors.put(error.getField(), localizedErrorMessage);
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}
}
Тепер повідомлення про помилки повертатимуться залежно від поточної локалі користувача!
Приклад запиту
Тіло запиту
{
"username": null,
"password": "password_that_is_too_long_for_the_application_rules"
}
Відповідь для локалі en
{
"username": "Field is required",
"password": "Field must not exceed 20 characters"
}
Відповідь для локалі ru
{
"username": "Поле обов'язкове для заповнення",
"password": "Поле не повинне перевищувати 20 символів"
}
Тепер твій Spring-додаток розуміє різні мови. Це додає професіоналізму і робить систему дружньою до користувача! Вітаю — ти офіційно впорався з локалізацією.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ