Spring Boot i18n: अंतर्राष्ट्रीयकरण सेटअप ट्यूटोरियल
MessageSource कॉन्फ़िगर करें, लोकेल-विशिष्ट प्रॉपर्टीज़ फ़ाइलें बनाएँ, लोकेल निर्धारित करें और बहुभाषी Thymeleaf टेम्पलेट रेंडर करें — फिर AI से अनुवाद स्वचालित करें।
डिपेंडेंसी जोड़ें
Spring Boot Starter Web में MessageSource का ऑटो-कॉन्फ़िगरेशन पहले से शामिल होता है। सर्वर पर रेंडर होने वाले i18n टेम्पलेट के लिए Thymeleaf और स्थानीयकृत त्रुटि संदेशों के लिए validation starter जोड़ें।
<!-- 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>MessageSource और LocaleResolver कॉन्फ़िगर करें
Spring का MessageSource basename परंपरा का उपयोग करके .properties फ़ाइलों से अनुवाद लोड करता है: messages.properties (डिफ़ॉल्ट), messages_de.properties (जर्मन), messages_ja.properties (जापानी)। हर अनुरोध के लिए किस लोकेल का उपयोग करना है, यह निर्धारित करने के लिए LocaleResolver कॉन्फ़िगर करें।
अनुवाद फ़ाइलें
# 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.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;
}
}लोकेल निर्धारण
कॉन्फ़िगर करें कि Spring हर अनुरोध के लिए सक्रिय लोकेल कैसे निर्धारित करे। CookieLocaleResolver सभी सेशन में यूज़र की पसंद बनाए रखता है। LocaleChangeInterceptor यूज़र को ?lang=de जैसे query parameter से लोकेल बदलने देता है।
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());
}
}कोड में अनुवादों का उपयोग करें
controllers में MessageSource injection के माध्यम से, Thymeleaf templates में #{...} syntax के साथ और REST APIs में अपने आप निर्धारित होने वाले Locale parameter का उपयोग करके अनुवादित संदेश प्राप्त करें।
MessageSource वाला Controller
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";
}
}Thymeleaf टेम्पलेट
Thymeleaf का #{...} expression आपकी .properties फ़ाइलों से message keys अपने आप निर्धारित करता है। #{key(arg0, arg1)} syntax से parameters पास करें। टेम्पलेट आपके 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>REST API स्थानीयकरण
REST APIs के लिए Spring, Accept-Language header से Locale अपने आप निर्धारित करता है। इसे method parameter के रूप में inject करें और MessageSource को पास करें। अलग-अलग Accept-Language headers भेजकर clients भाषा बदल सकते हैं।
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!"}
}Bean Validation संदेश
Spring आपके MessageSource से validation constraint messages अपने आप निर्धारित करता है। अपने constraint annotations में {validation.name.required} जैसे curly-brace placeholders का उपयोग करें और अनुवादों को अपनी .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 einबहुवचन और वेरिएबल संभालें
Spring interpolation और बहुवचन के लिए java.text.MessageFormat का उपयोग करता है। ChoiceFormat pattern सामान्य बहुवचन नियमों को संभालता है, लेकिन संपूर्ण ICU plural support (अरबी के 6 रूप, रूसी के 3 रूप) के लिए ICU4J library जोड़ें।
# 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}अनुवाद स्वचालित करें
अपना i18n सेटअप पूरा करने के बाद AI का उपयोग करके अपनी .properties फ़ाइलों का अनुवाद करें। अपने IDE में अपने AI assistant से source file का अनुवाद करने के लिए कहें या अपनी CI/CD pipeline में i18n Agent CLI का उपयोग करें।
# 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,esअनुवाद की गुणवत्ता स्वचालित रूप से सुनिश्चित करें
spring-locale-chain के साथ बिना कॉन्फ़िगरेशन के शुरुआत करें
spring-locale-chain एक open-source Spring Boot starter है, जो एक ही dependency से LocaleResolver, LocaleChangeInterceptor और supported-locale validation को अपने आप कॉन्फ़िगर करता है। application.yml में अपने समर्थित locales परिभाषित करें और बाकी काम library संभाल लेगी।
<!-- 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>सुझाई गई फ़ाइल संरचना
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.gradleआम समस्याएँ
Non-ASCII वर्ण विकृत टेक्स्ट के रूप में दिखाई देते हैं
गैर-अंग्रेज़ी बहुवचनों के साथ ChoiceFormat काम नहीं करता
अनुवाद में किए गए बदलाव दिखाई नहीं देते
अनपेक्षित रूप से JVM Locale का fallback उपयोग होता है
इनका भी अनुवाद करें:
i18n Agent अभी आज़माएँ
अपनी अनुवाद फ़ाइल यहाँ छोड़ें
JSON, YAML, PO, XML, CSV, Markdown, Properties
या ब्राउज़ करने के लिए क्लिक करें
लक्षित भाषाएँ
spring-locale-chain के साथ Locale Fallback
जब pt-BR जैसे regional locale में कोई translation key गायब होती है, तो Spring Boot पहले parent locale pt को जाँचने के बजाय सीधे default locale पर चला जाता है।
<!-- 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
- enसमर्थित frameworks और पहले से मौजूद 75 chains की पूरी सूची के लिए हमारी Locale Fallback Guide देखें। Learn more →