Локализация в IT — это как переводчик на конференции: пользователи говорят на разных языках, а система должна отвечать им понятно. Представьте, что вы разрабатываете приложение, которое выходит на мировой рынок. Для пользователей из разных стран важно, чтобы интерфейс, ошибки и уведомления были адаптированы под их язык и культурные особенности.
Что локализуем?
- Сообщения об ошибках: например, вместо сухого
must not be null, пользователь из России должен видеть:Поле не может быть пустым. - Валидационные сообщения: когда форма заполнена неверно, текст предупреждений тоже должен быть на языке пользователя.
- Другие уведомления: информация о некорректном вводе дат, чисел, email-ов и т.д.
Как работает локализация в Spring?
Spring предоставляет мощный инструмент для локализации — MessageSource. Это компонент, который отвечает за работу с текстами и поддерживает множественные языковые файлы.
Компоненты локализации
- Языковые файлы: это обычные
.propertiesфайлы с ключами и их значениями, например:messages_en.propertiesдля английского.messages_ru.propertiesдля русского.
- MessageSource: Bean, который ищет нужный файл в зависимости от текущей локали.
- LocaleResolver: определяет, какая локаль активна для текущего пользователя.
Настройка локализации в Spring-приложении
1. Подключение библиотеки
Для начала убедитесь, что у вас подключены зависимости веб и валидации в 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-приложение понимает разные языки. Это добавляет профессионализма и делает систему дружественной к пользователю! Вы официально справились с локализацией.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ