Spring boot internalization does not work per request

I know this question might have an answer but am a newbie to spring boot. I need to do internalization to my rest endpoints and I followed this blog to implement internalization but the problem is one. The language does not change per request it only change only after application launch that is suppose at launch in my post man the language was fr that will work but after I change fr to pt (Portuguese) it does not pick pt it still remains with fr. Here is my code that am working with. I have created 4 different messages.properties that is messages_fr.properties, messages_pt.properties, messages_sw.properties under resources dir

@Configuration
public class MyCustomLocaleResolver extends AcceptHeaderLocaleResolver
        implements WebMvcConfigurer {
    List<Locale> LOCALES = Arrays.asList(
            new Locale("en"),
            new Locale("pt"),
            new Locale("sw"),
            new Locale("fr"));

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String headerLang = request.getHeader("Accept-Language");
        System.out.println("header:"+headerLang);
        return headerLang == null || headerLang.isEmpty()
                ? Locale.getDefault()
                : Locale.lookup(Locale.LanguageRange.parse(headerLang), LOCALES);
    }

    @Bean
    public MessageSource messageSource() {
        final ResourceBundleMessageSource rs = new ResourceBundleMessageSource();
        rs.setDefaultEncoding(StandardCharsets.ISO_8859_1.name());
        rs.setBasename("messages");

        rs.setUseCodeAsDefaultMessage(true);
        return rs;
    }

}

And Translator class

@Component
public class LanguageTranslator {

    private static ResourceBundleMessageSource messageSource;

    @Autowired
    LanguageTranslator(ResourceBundleMessageSource messageSource) {
        LanguageTranslator.messageSource = messageSource;
    }

    public static String translate(String msg) {
        Locale locale = LocaleContextHolder.getLocale();
        return messageSource.getMessage(msg, null, locale);
    }
}

And here is my postman request enter image description here and here is messages_fr.properties

enter image description here and project structure enter image description here

And here is my controller code

@RestController
@RequestMapping("/home")
public class HomeContoller {

    @Autowired
    private SystemSettingService settingService;



    @GetMapping("/")
    public String home() {

        return "Home page";
    }

    @RequestMapping(value = "/demo", method = RequestMethod.POST)
    public ResponseEntity all_menu_assignment(HttpServletRequest req)  {
   

        return  ResponseEntity
                .ok().body(new ServerResponse(Common.SUCCESS_CODE,Common.SUCCESS_MESSAGE));

    }
}

and here is my Common class

public class Common{
  public static String SUCCESS_MESSAGE= LanguageTranslator.translate("SUCCESS_MESSAGE");
}

Answer

The LocaleContextHolder holds the locale of the current thread – so referencing this in a static variable will result in the default VM local to be used (because the constant will be initialized during startup).

Something like this should work:

@RestController
@RequestMapping("/home")
public class HomeContoller {

    @Autowired
    private SystemSettingService settingService;

    @GetMapping("/")
    public String home() {

        return "Home page";
    }

    @RequestMapping(value = "/demo", method = RequestMethod.POST)
    public ResponseEntity all_menu_assignment(HttpServletRequest req)  {
   

        return  ResponseEntity
                .ok().body(new ServerResponse(Common.SUCCESS_CODE, LanguageTranslator.translate("SUCCESS_MESSAGE")));

    }
}

Also, it would be better make the translate method in LanguageTranslator non-static and to inject (autowire) the object in the controller.

Leave a Reply

Your email address will not be published. Required fields are marked *