Learnitweb

Internationalization (i18n) in Spring Boot

Internationalization (i18n) is the process of designing applications that can be adapted to different languages and regions without requiring code changes. In Spring Boot, this is typically achieved using MessageSource to manage locale-specific messages and configuring locale resolvers.

1. Setting Up MessageSource Bean

Spring Boot automatically loads messages from property files in the src/main/resources directory. Create message property files for different locales:

Example files:

src/main/resources/messages_en.properties

welcome.message=Welcome to our application!

src/main/resources/messages_fr.properties

welcome.message=Bienvenue dans notre application!

To enable message localization, configure a MessageSource bean in a Spring Boot configuration class:

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 InternationalizationConfig {
    
    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}

2. Configuring Locale Resolver

Spring Boot provides multiple ways to resolve locales. The most common is SessionLocaleResolver or AcceptHeaderLocaleResolver.

Using AcceptHeaderLocaleResolver

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

import java.util.Locale;

@Configuration
public class LocaleConfig {
    
    @Bean
    public LocaleResolver localeResolver() {
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(Locale.ENGLISH);
        return localeResolver;
    }
}

This resolver reads the Accept-Language header from HTTP requests to determine the locale.

3. Using Messages in Controllers

Inject the MessageSource bean into a controller and fetch messages dynamically.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Locale;

@RestController
public class GreetingController {
    
    @Autowired
    private MessageSource messageSource;
    
    @GetMapping("/greet")
    public String greet(@RequestHeader(name = "Accept-Language", required = false) Locale locale) {
        return messageSource.getMessage("welcome.message", null, locale);
    }
}

4. Testing the API

Start your Spring Boot application and test using Postman or a browser.

English Request:

GET /greet
Accept-Language: en

Response: Welcome to our application!

French Request:

GET /greet
Accept-Language: fr

Response: Bienvenue dans notre application!

5. Handling Locale Change via URL Parameter

Instead of using Accept-Language header, you can configure LocaleChangeInterceptor to switch locale via request parameters.

Modify Configuration:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.util.Locale;

@Configuration
public class LocaleConfig {
    
    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.ENGLISH);
        return localeResolver;
    }
    
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang");
        return interceptor;
    }
}

Update Web Config to Register Interceptor

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Autowired
    private LocaleChangeInterceptor localeChangeInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor);
    }
}

Testing via URL Parameter:

http://localhost:8080/greet?lang=fr

Response: Bienvenue dans notre application!

Conclusion

Internationalization in Spring Boot is easy with MessageSource, LocaleResolver, and LocaleChangeInterceptor. By supporting multiple languages, your application can reach a global audience efficiently.