Gereksinimler ve Ön Hazırlık
Uygulamaya başlamadan önce sisteminizde Java 17 veya üzeri bir sürümün yüklü olduğundan emin olun. Spring Boot 3.x sürümleri ile tam uyumlu bir çalışma ortamı için aşağıdaki yapılandırmaları kontrol etmelisiniz.
- JDK 17+: Modern dil özellikleri ve performans iyileştirmeleri için gereklidir.
- Maven veya Gradle: Bağımlılık yönetimi için standart araçlar.
- IDE: IntelliJ IDEA veya Eclipse gibi Spring desteği olan bir geliştirme ortamı.
Projenizde spring-boot-starter-web bağımlılığının tanımlı olması yeterlidir. Ekstra bir kütüphane kurulumuna gerek kalmadan Spring'in çekirdek özelliklerini kullanacağız.
Adım 1: Mesaj Kaynaklarını (Message Bundles) Oluşturma
Spring Boot, çoklu dil desteği için ResourceBundleMessageSource sınıfını kullanır. Bu sınıf, src/main/resources dizini altında bulunan messages_xx.properties dosyalarını otomatik olarak okur. "xx" kısmı dil kodunu (örneğin tr, en) temsil eder.
# messages.properties (Varsayılan dil - İngilizce)
welcome.message=Welcome to our application!
login.button=Login
# messages_tr.properties (Türkçe)
welcome.message=Uygulamamıza hoş geldiniz!
login.button=Giriş Yap
Bu dosyalar, anahtar-değer çiftlerinden oluşur. Spring, Locale nesnesine göre doğru dosyayı otomatik olarak seçecektir. Dosyaların UTF-8 kodlamasında kaydedildiğinden emin olun; aksi takdirde Türkçe karakter sorunları yaşayabilirsiniz.
Adım 2: LocaleResolver Yapılandırması
Uygulamanızın kullanıcının hangi dili tercih ettiğini anlaması için bir LocaleResolver bean'ine ihtiyacı vardır. Varsayılan olarak Spring, HTTP isteğindeki Accept-Language başlığını (header) kullanır. Ancak, kullanıcıya dil değiştirme butonu sunmak istiyorsanız SessionLocaleResolver veya CookieLocaleResolver kullanmanız önerilir.
@Configuration
public class LocaleConfig {
@Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
resolver.setCookieName("lang_cookie");
return resolver;
}
}
Bu konfigürasyon, kullanıcının dil tercihini bir çerezde (cookie) saklar. Böylece kullanıcı sayfayı yenilediğinde veya tekrar geldiğinde seçtiği dil korunur.
Adım 3: LocaleChangeInterceptor ile Dil Değişimi
Kullanıcının bir URL parametresi (örneğin ?lang=tr) üzerinden dil değiştirebilmesini sağlamak için LocaleChangeInterceptor sınıfını kullanırız. Bu interceptor, gelen isteği dinler ve parametreye göre dili günceller.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
registry.addInterceptor(interceptor);
}
}
Bu yapılandırma ile /home?lang=tr adresine gidildiğinde, sistem otomatik olarak Türkçe mesajları getirecektir.
Adım 4: Controller ve View Katmanında Kullanım
Mesajları Controller içerisinde veya Thymeleaf gibi bir şablon motorunda kullanmak oldukça basittir. Spring, MessageSource arayüzünü enjekte ederek mesajlara erişmemizi sağlar.
@Controller
public class HomeController {
@Autowired
private MessageSource messageSource;
@GetMapping("/home")
public String home(Model model, Locale locale) {
String welcome = messageSource.getMessage("welcome.message", null, locale);
model.addAttribute("message", welcome);
return "index";
}
}
Eğer Thymeleaf kullanıyorsanız, HTML içerisinde #{welcome.message} sözdizimi ile mesajları doğrudan çağırabilirsiniz. Bu, kodunuzu temiz ve yönetilebilir kılar.
Adım 5: Çoklu Dil Desteği Yöntemlerinin Karşılaştırılması
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| CookieLocaleResolver | Kullanıcı oturumundan bağımsızdır. | Çerezler silinirse tercih kaybolur. |
| SessionLocaleResolver | Sunucu tarafında güvenli saklanır. | Sunucu belleğini kullanır. |
| AcceptHeaderLocaleResolver | Ek yapılandırma gerektirmez. | Kullanıcı dilini değiştiremez. |
Adım 6: Hata Yönetimi ve Güvenlik Uyarıları
Çoklu dil desteği eklerken, eksik anahtarlar (missing keys) uygulamanızın hata vermesine neden olabilir. Bu durumu yönetmek için MessageSource yapılandırmasında setUseCodeAsDefaultMessage(true) metodunu kullanabilirsiniz.
Kritik Güvenlik Uyarısı: Dil dosyalarınızı (properties) dışarıdan erişilebilir dizinlere koymayın. Ayrıca, kullanıcıdan gelen lang parametresini asla doğrudan veritabanı sorgularında veya dosya yolu oluşturmada kullanmayın; bu durum SQL Injection veya Path Traversal saldırılarına yol açabilir. Her zaman beklenen dil kodlarını (tr, en, de) bir liste ile valide edin.
Sıkça Sorulan Sorular
Dinamik içerikleri (veritabanından gelen) nasıl çevirebilirim?
Veritabanındaki içerikler için genellikle "Locale" tabanlı bir yapı kurmanız gerekir. Örneğin, bir ürünün adını product_name_tr ve product_name_en gibi sütunlarda tutabilir veya ayrı bir çeviri tablosu oluşturarak ilişkilendirebilirsiniz.
Neden Türkçe karakterler bozuk görünüyor?
Java'nın standart Properties sınıfı varsayılan olarak ISO-8859-1 kodlamasını kullanır. IDE ayarlarınızdan properties dosyalarının UTF-8 olarak kaydedildiğinden ve Spring Boot'un bunu tanıdığından emin olun.
Uygulama çalışırken dil dosyalarını güncelleyebilir miyim?
Evet, MessageSource bean'i üzerinde setCacheSeconds(int) metodunu kullanarak dosyaların ne sıklıkla tekrar okunacağını belirleyebilirsiniz. 0 değeri, her istekte dosyaların tekrar okunmasını sağlar (geliştirme aşaması için uygundur).
Mobil uygulamalar için farklı bir yöntem mi izlemeliyim?
Mobil uygulamalar (REST API) için AcceptHeaderLocaleResolver en yaygın tercihtir. Mobil istemci, isteğin header kısmına dil bilgisini ekler ve API buna göre JSON yanıtını yerelleştirir.
Çeviri dosyalarım çok büyürse ne yapmalıyım?
Dosyaları messages_tr.properties yerine messages/auth_tr.properties, messages/product_tr.properties gibi modüllere ayırabilir ve Basenames listesine ekleyebilirsiniz.
Çoklu Dil Desteğinde Performans Optimizasyonu ve Önbellekleme
Spring Boot uygulamalarında MessageSource kullanımı, her istekte dosya sistemine erişim sağlayabilir. Küçük projelerde bu bir sorun teşkil etmese de, yüksek trafikli uygulamalarda disk I/O operasyonlarını minimize etmek hayati önem taşır. Spring, varsayılan olarak mesajları önbelleğe alır, ancak bu süreyi projenizin ihtiyaçlarına göre optimize edebilirsiniz.
application.properties dosyanızda aşağıdaki ayarları yaparak önbellek davranışını kontrol edebilirsiniz:
# Mesajların önbellekte tutulma süresi (saniye cinsinden)
# -1 değeri, mesajların uygulama kapanana kadar önbellekte kalacağını belirtir.
spring.messages.cache-duration=3600
# Mesajların her zaman yeniden yüklenmesini sağlar (Geliştirme ortamı için önerilir)
spring.messages.always-use-message-format=true
Eğer çok sayıda dil dosyası ve mesaj anahtarı ile çalışıyorsanız, ReloadableResourceBundleMessageSource sınıfını manuel olarak yapılandırarak bellek kullanımını yönetebilirsiniz:
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
// Önbellek süresini 1 saat olarak ayarla
messageSource.setCacheSeconds(3600);
return messageSource;
}
Çoklu Dil Desteği İçin Birim Testleri (Unit Testing)
Uygulamanızın farklı dillerde doğru mesajları döndürdüğünden emin olmak için MessageSource bileşenini test etmek kritik bir adımdır. JUnit ve MockMvc kullanarak, belirli bir Locale için beklenen çıktının doğruluğunu şu şekilde test edebilirsiniz:
@SpringBootTest
class LocalizationTests {
@Autowired
private MessageSource messageSource;
@Test
void testTurkishGreeting() {
String message = messageSource.getMessage("welcome.message", null, new Locale("tr", "TR"));
assertEquals("Hoş geldiniz!", message);
}
@Test
void testEnglishGreeting() {
String message = messageSource.getMessage("welcome.message", null, Locale.ENGLISH);
assertEquals("Welcome!", message);
}
}
Bu testler, dil dosyalarınızda bir anahtar eksik olduğunda veya yanlış bir çeviri yapıldığında CI/CD süreçlerinizin hata vermesini sağlayarak, üretim ortamında oluşabilecek "kırık metin" sorunlarını engeller.
İleri Seviye: Dinamik Parametre ve Çoğul Eki Yönetimi
Mesajlarınızda sadece statik metinler değil, dinamik veriler ve çoğul ekleri (pluralization) de kullanmanız gerekebilir. Spring, MessageFormat kütüphanesini temel aldığı için mesaj dosyalarınızda şu yapıyı kullanabilirsiniz:
# messages_tr.properties
items.count=Sepetinizde {0} adet ürün bulunmaktadır.
items.plural=Sepetinizde {0, choice, 0#hiç ürün yok|1#bir ürün var|1
Sonuç
Java ile Spring Boot üzerinde çoklu dil desteği yapmak, projenizin profesyonellik seviyesini artıran ve kullanıcı deneyimini iyileştiren temel bir yetenektir. Bu rehberde öğrendiğiniz LocaleResolver ve MessageSource yapıları, ölçeklenebilir ve sürdürülebilir bir sistem kurmanız için yeterlidir.
Bir sonraki adım olarak, çeviri süreçlerini otomatize etmek için veritabanı tabanlı bir MessageSource implementasyonu yazmayı deneyebilir veya profesyonel çeviri platformları (Crowdin, Lokalise gibi) ile entegrasyon sağlayabilirsiniz. Kod güvenliği konusunda her zaman kullanıcı girdilerini filtrelemeyi ve güncel kütüphaneleri takip etmeyi unutmayın.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamına almadan önce güvenlik testlerinden geçirilmesi ve projenizin özel ihtiyaçlarına göre konfigüre edilmesi geliştiricinin sorumluluğundadır.

Yorumlar (0)
Yorum Yaz