Spring Boot i18n: vodnik za nastavitev internacionalizacije
Nastavite MessageSource, ustvarite datoteke z lastnostmi za posamezne področne nastavitve, razrešujte področne nastavitve in upodabljajte večjezične predloge Thymeleaf, nato pa avtomatizirajte prevode z umetno inteligenco.
Dodajte odvisnosti
Spring Boot Starter Web že vključuje samodejno konfiguracijo MessageSource. Dodajte Thymeleaf za strežniško upodobljene predloge i18n in začetni paket za preverjanje veljavnosti za lokalizirana sporočila o napakah.
<!-- pom.xml — Spring Boot Starter Web includes MessageSource auto-config -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Thymeleaf for server-side rendered templates with i18n -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- Validation (for localized error messages) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>Nastavite MessageSource in LocaleResolver
Springov MessageSource nalaga prevode iz datotek .properties po dogovoru o osnovnem imenu: messages.properties (privzeto), messages_de.properties (nemščina), messages_ja.properties (japonščina). Nastavite LocaleResolver, da določite področne nastavitve za posamezno zahtevo.
Prevajalske datoteke
# src/main/resources/messages.properties (default / English)
nav.home=Home
nav.about=About
nav.settings=Settings
greeting=Hello, {0}!
cart.itemCount={0,choice,0#No items|1#1 item|1<{0,number} items}
error.notFound=Page not found
error.serverError=Something went wrong. Please try again.Konfiguracija MessageSource
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
@Configuration
public class I18nConfig {
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource source =
new ReloadableResourceBundleMessageSource();
source.setBasename("classpath:messages");
source.setDefaultEncoding("UTF-8");
source.setCacheSeconds(3600); // reload interval in dev
return source;
}
// Wire MessageSource into Bean Validation
@Bean
public LocalValidatorFactoryBean validator(MessageSource messageSource) {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource);
return bean;
}
}Razreševanje področnih nastavitev
Nastavite, kako Spring določi aktivne področne nastavitve za posamezno zahtevo. CookieLocaleResolver ohrani uporabnikovo izbiro med sejami. LocaleChangeInterceptor uporabnikom omogoča preklapljanje področnih nastavitev s poizvedbenim parametrom, kot je ?lang=de.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import java.util.Locale;
@Configuration
public class LocaleConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver("lang");
resolver.setDefaultLocale(Locale.ENGLISH);
resolver.setCookieMaxAge(3600 * 24 * 365); // 1 year
return resolver;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang"); // ?lang=de switches locale
return interceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}Uporabite prevode v kodi
Do prevedenih sporočil v krmilnikih dostopajte z vbrizgavanjem MessageSource, v predlogah Thymeleaf s skladnjo #{...}, v vmesnikih REST API pa s samodejno razrešenim parametrom Locale.
Krmilnik z MessageSource
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Locale;
@Controller
public class HomeController {
private final MessageSource messageSource;
public HomeController(MessageSource messageSource) {
this.messageSource = messageSource;
}
@GetMapping("/")
public String home(Model model, Locale locale) {
// Spring injects the resolved Locale automatically
String greeting = messageSource.getMessage(
"greeting",
new Object[]{"World"},
locale
);
model.addAttribute("greeting", greeting);
return "home";
}
}Predloge Thymeleaf
Thymeleafov izraz #{...} samodejno razreši ključe sporočil iz Vaših datotek .properties. Parametre posredujte s skladnjo #{key(arg0, arg1)}. Predloga uporabi področne nastavitve, ki jih razreši Vaš LocaleResolver.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="#{nav.home}">Home</title>
</head>
<body>
<!-- Simple message lookup -->
<h1 th:text="#{greeting('World')}">Hello, World!</h1>
<!-- Navigation with i18n -->
<nav>
<a href="/" th:text="#{nav.home}">Home</a>
<a href="/about" th:text="#{nav.about}">About</a>
<a href="/settings" th:text="#{nav.settings}">Settings</a>
</nav>
<!-- Parameterized messages -->
<p th:text="#{cart.itemCount(3)}">3 items</p>
<!-- Language switcher -->
<div>
<a th:href="@{/(lang=en)}">English</a>
<a th:href="@{/(lang=de)}">Deutsch</a>
<a th:href="@{/(lang=ja)}">日本語</a>
</div>
<!-- Conditional text based on locale -->
<p th:if="${#locale.language == 'ja'}"
th:text="#{greeting('ユーザー')}">
こんにちは、ユーザーさん!
</p>
</body>
</html>Lokalizacija vmesnika REST API
Spring za vmesnike REST API samodejno razreši Locale iz glave Accept-Language. Vbrizgajte ga kot parameter metode in ga posredujte MessageSource. Odjemalci preklapljajo med jeziki tako, da pošiljajo različne glave Accept-Language.
import org.springframework.context.MessageSource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Locale;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class ApiController {
private final MessageSource messageSource;
public ApiController(MessageSource messageSource) {
this.messageSource = messageSource;
}
@GetMapping("/greeting/{name}")
public ResponseEntity<Map<String, String>> greeting(
@PathVariable String name,
Locale locale) { // Resolved from Accept-Language header
String msg = messageSource.getMessage(
"greeting", new Object[]{name}, locale
);
return ResponseEntity.ok(Map.of("message", msg));
}
// curl -H "Accept-Language: de" localhost:8080/api/greeting/Max
// → {"message": "Hallo, Max!"}
}Sporočila preverjanja veljavnosti gradnikov
Spring samodejno razreši sporočila omejitev preverjanja veljavnosti iz Vašega MessageSource. V pripisih omejitev uporabite označbe v zavitih oklepajih, kot je {validation.name.required}, prevode pa določite v datotekah .properties.
import jakarta.validation.constraints.*;
public class CreateUserRequest {
@NotBlank(message = "{validation.name.required}")
@Size(min = 2, max = 50, message = "{validation.name.size}")
private String name;
@Email(message = "{validation.email.invalid}")
private String email;
}
// In messages.properties:
// validation.name.required=Name is required
// validation.name.size=Name must be between {min} and {max} characters
// validation.email.invalid=Please enter a valid email address
//
// In messages_de.properties:
// validation.name.required=Name ist erforderlich
// validation.name.size=Name muss zwischen {min} und {max} Zeichen lang sein
// validation.email.invalid=Bitte geben Sie eine gültige E-Mail-Adresse einObravnavajte množinske oblike in spremenljivke
Spring za vstavljanje vrednosti in množinske oblike uporablja java.text.MessageFormat. Vzorec ChoiceFormat obravnava osnovna pravila za množinske oblike, za popolno podporo množinskim oblikam ICU (6 oblik v arabščini, 3 v ruščini) pa dodajte knjižnico ICU4J.
# MessageFormat plural syntax in messages.properties
# Uses java.text.ChoiceFormat — NOT ICU plural rules
cart.itemCount={0,choice,0#No items|1#1 item|1<{0,number} items}
# For more complex plurals, use ICU4J:
# 1. Add dependency: com.ibm.icu:icu4j
# 2. Use ICUMessageSource instead of ResourceBundleMessageSource
#
# Then you can write ICU-style plurals:
# cart.items={count, plural, one {# item} other {# items}}
# Variables with MessageFormat:
welcome.message=Welcome, {0}! You have {1,number} new {1,choice,1#notification|1<notifications}.
order.total=Order total: {0,number,currency}
event.date=Event date: {0,date,long}Avtomatizirajte prevode
Ko je nastavitev i18n končana, prevedite datoteke .properties z umetno inteligenco. V svojem razvojnem okolju prosite pomočnika z umetno inteligenco, naj prevede izvorno datoteko, ali pa v cevovodu CI/CD uporabite vmesnik ukazne vrstice i18n Agent.
# Translate your .properties files with AI
# In your IDE, ask your AI assistant:
> Translate src/main/resources/messages.properties to German, Japanese, and Spanish
✓ messages_de.properties created (1.2s)
✓ messages_ja.properties created (1.5s)
✓ messages_es.properties created (1.1s)
# Or use the CLI in CI/CD:
npx i18n-agent translate src/main/resources/messages.properties --lang de,ja,esAvtomatizirajte zagotavljanje kakovosti prevodov
Nastavitev brez konfiguracije s spring-locale-chain
spring-locale-chain je odprtokodni začetni paket za Spring Boot, ki z eno odvisnostjo samodejno nastavi LocaleResolver, LocaleChangeInterceptor in preverjanje podprtih področnih nastavitev. Podprte področne nastavitve določite v application.yml, knjižnica pa poskrbi za vse drugo.
<!-- Add spring-locale-chain for zero-config locale resolution -->
<dependency>
<groupId>io.github.i18n-agent</groupId>
<artifactId>spring-locale-chain</artifactId>
<version>1.0.0</version>
</dependency>Priporočena struktura datotek
my-spring-app/
├── src/main/
│ ├── java/com/example/
│ │ ├── config/
│ │ │ ├── I18nConfig.java # MessageSource bean
│ │ │ └── LocaleConfig.java # LocaleResolver + interceptor
│ │ ├── controller/
│ │ │ └── HomeController.java # Uses MessageSource
│ │ └── MyApplication.java
│ └── resources/
│ ├── messages.properties # Default (English)
│ ├── messages_de.properties # German
│ ├── messages_ja.properties # Japanese
│ ├── messages_es.properties # Spanish
│ ├── application.yml # Spring config
│ └── templates/
│ └── home.html # Thymeleaf with #{...}
├── pom.xml
└── build.gradlePogoste pasti
Znaki zunaj nabora ASCII so prikazani napačno
ChoiceFormat ne deluje pravilno pri neangleških množinskih oblikah
Spremembe prevodov niso vidne
Nepričakovana uporaba področnih nastavitev JVM
Preizkusite i18n Agent zdaj
Spustite prevajalsko datoteko sem
JSON, YAML, PO, XML, CSV, Markdown, Properties
ali kliknite za izbiro
Ciljni jeziki
Nadomestne področne nastavitve s spring-locale-chain
Ko v regionalnih področnih nastavitvah, kot je pt-BR, manjka prevajalski ključ, Spring Boot takoj uporabi privzete področne nastavitve, namesto da bi najprej preveril nadrejene področne nastavitve pt.
<!-- Maven -->
<dependency>
<groupId>ai.i18nagent</groupId>
<artifactId>spring-locale-chain</artifactId>
</dependency># application.yml
locale-chain:
fallbacks:
pt-BR:
- pt
- en
zh-Hant-HK:
- zh-Hant
- zh
- enCeloten seznam podprtih ogrodij in 75 vgrajenih verig najdete v našem vodniku po nadomestnih področnih nastavitvah. Learn more →