Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Spring - Resource Bundle Message Source (i18n)

Internationalization (often abbreviated as i18n) is the process of designing applications so they can be adapted to various languages and regions without engineering changes. Spring provides excellent support for internationalization (i18n) using the MessageSource interface, and one of its implementations is ResourceBundleMessageSource.

Here's how you can set up internationalization in Spring using the ResourceBundleMessageSource:

1. Property Files for Different Locales

Create property files with messages for different languages. By convention, the files have a base name followed by the locale.

For example:

  • messages_en.properties (English locale)
greeting=Hello
  • messages_fr.properties (French locale)
greeting=Bonjour

2. Configure ResourceBundleMessageSource in Spring XML Configuration

Configure the ResourceBundleMessageSource bean in your Spring XML configuration:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="messages" />
    </bean>

</beans>

3. Using Messages in the Application

You can use the MessageSource to retrieve messages for different locales:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Locale;

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // Get the message for English locale
        String englishGreeting = context.getMessage("greeting", null, Locale.ENGLISH);
        System.out.println(englishGreeting);  // Outputs: Hello

        // Get the message for French locale
        String frenchGreeting = context.getMessage("greeting", null, Locale.FRENCH);
        System.out.println(frenchGreeting);  // Outputs: Bonjour
    }
}

4. Using in Spring Web MVC

If you're using Spring MVC, you can also inject Locale into your controllers to fetch locale-specific messages.

@Controller
public class GreetingController {

    @Autowired
    private MessageSource messageSource;

    @RequestMapping("/greet")
    public String greet(Locale locale, Model model) {
        String greetingMessage = messageSource.getMessage("greeting", null, locale);
        model.addAttribute("greeting", greetingMessage);
        return "greetingPage";
    }
}

The Locale object injected into the controller method represents the client's locale, and Spring automatically resolves it.

Note:

Don't forget to have the message properties files in the classpath. If they're in a directory/package named resources, then the basename would be resources.messages.

This setup allows your application to display messages based on the user's locale, providing a more tailored user experience.

  1. Spring ResourceBundleMessageSource example:

    • Description: ResourceBundleMessageSource is a Spring class that resolves messages from resource bundles.

    • Code Example:

      @Configuration
      public class AppConfig {
      
          @Bean
          public MessageSource messageSource() {
              ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
              messageSource.setBasename("messages");
              return messageSource;
          }
      }
      
  2. Internationalization in Spring Framework:

    • Description: Internationalization (i18n) in Spring allows for supporting multiple languages in an application.

    • Code Example (Using LocaleContextHolder):

      String message = messageSource.getMessage("greeting", null, LocaleContextHolder.getLocale());
      
  3. How to use Resource Bundle in Spring:

    • Description: Resource bundles contain locale-specific objects.

    • Code Example (messages.properties):

      greeting=Hello, {0}!
      
  4. Spring MessageSource configuration:

    • Description: The MessageSource bean is configured to use a ResourceBundleMessageSource in the application context.

    • Code Example:

      @Configuration
      public class AppConfig {
      
          @Bean
          public MessageSource messageSource() {
              ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
              messageSource.setBasename("messages");
              return messageSource;
          }
      }
      
  5. Spring i18n properties file:

    • Description: Properties files are commonly used for i18n to store messages for different locales.

    • Code Example (messages_fr.properties):

      greeting=Bonjour, {0}!
      
  6. LocaleResolver in Spring:

    • Description: LocaleResolver is responsible for resolving the locale of the current user.

    • Code Example (Using AcceptHeaderLocaleResolver):

      @Bean
      public LocaleResolver localeResolver() {
          AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
          resolver.setDefaultLocale(Locale.US);
          return resolver;
      }
      
  7. Spring MessageSource reloadable:

    • Description: ReloadableResourceBundleMessageSource allows reloading of message bundles without restarting the application.

    • Code Example:

      @Bean
      public MessageSource messageSource() {
          ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
          messageSource.setBasename("classpath:messages");
          messageSource.setDefaultEncoding("UTF-8");
          messageSource.setCacheSeconds(3600);
          return messageSource;
      }
      
  8. Spring MVC internationalization example:

    • Description: Spring MVC controllers can be configured to support internationalization.

    • Code Example (Controller Method):

      @GetMapping("/greet")
      public String greet(Model model) {
          String message = messageSource.getMessage("greeting", null, LocaleContextHolder.getLocale());
          model.addAttribute("message", message);
          return "greet";
      }
      
  9. Spring Boot i18n example:

    • Description: Spring Boot simplifies internationalization with auto-configuration.

    • Code Example (application.properties):

      spring.messages.basename=messages
      
  10. MessageSourceAccessor in Spring:

    • Description: MessageSourceAccessor provides convenient methods to access messages.

    • Code Example:

      @Autowired
      private MessageSourceAccessor messageSourceAccessor;
      String message = messageSourceAccessor.getMessage("greeting", "John");
      
  11. Spring ResourceBundleMessageSource vs ReloadableResourceBundleMessageSource:

    • Description: ResourceBundleMessageSource is for static messages, while ReloadableResourceBundleMessageSource allows dynamic reloading.

    • Code Example (ResourceBundleMessageSource):

      @Bean
      public MessageSource messageSource() {
          ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
          messageSource.setBasename("messages");
          return messageSource;
      }
      
    • Code Example (ReloadableResourceBundleMessageSource):

      @Bean
      public MessageSource messageSource() {
          ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
          messageSource.setBasename("classpath:messages");
          messageSource.setDefaultEncoding("UTF-8");
          return messageSource;
      }
      
  12. Spring Boot custom message source:

    • Description: Spring Boot allows customizing the message source.

    • Code Example (Custom Message Source):

      @SpringBootApplication
      public class MyApp {
      
          @Bean
          public MessageSource messageSource() {
              // Custom message source configuration
              return new MyCustomMessageSource();
          }
      
          public static void main(String[] args) {
              SpringApplication.run(MyApp.class, args);
          }
      }
      
  13. Spring i18n UTF-8 encoding:

    • Description: To support UTF-8 encoding for internationalized messages, set the default encoding in the message source.

    • Code Example (ReloadableResourceBundleMessageSource):

      @Bean
      public MessageSource messageSource() {
          ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
          messageSource.setBasename("classpath:messages");
          messageSource.setDefaultEncoding("UTF-8");
          return messageSource;
      }
      
  14. Handling multiple languages in Spring MVC:

    • Description: Spring MVC can handle multiple languages based on the user's locale.

    • Code Example (Using LocaleChangeInterceptor):

      @Configuration
      public class AppConfig implements WebMvcConfigurer {
      
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
              LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
              localeChangeInterceptor.setParamName("lang");
              registry.addInterceptor(localeChangeInterceptor);
          }
      }
      
  15. Spring Boot change default locale:

    • Description: Change the default locale in Spring Boot to a different language.

    • Code Example (application.properties):

      spring.mvc.locale=defaultLocale
      
  16. Spring Boot change language dynamically:

    • Description: Change the user's language dynamically during runtime.

    • Code Example (Controller Method):

      @GetMapping("/changeLanguage")
      public String changeLanguage(@RequestParam String lang, HttpServletRequest request, HttpServletResponse response) {
          Locale locale = new Locale(lang);
          localeResolver.setLocale(request, response, locale);
          return "redirect:/";
      }