irotsoma
irotsoma

Reputation: 705

Spring Boot Controller Locale Not Changing with Parameter

I'm having some trouble with using Spring Boot with Kotlin to handle locale. I created these settings in my application.properties file:

spring.messages.basename=messages/messages
spring.messages.cache-seconds=-1
spring.messages.encoding=UTF-8

Then created an autowired instance of MessageSource in my controller:

@Autowired
lateinit var messageSource: MessageSource

When put a locale in the url as a parameter, the parameter doesn't seem to get picked up when I call LocaleContextHolder.getLocale(), so it is always en_US. Though, I can manually pick it up using @RequestParam(value="locale") locale: Locale as a parameter to my controller function and use it from there in the controller function, but not in other functions. I thought that spring boot LocaleContextHolder was supposed to hold the current locale based on the request URL automatically for the whole session.

I read an older article that mentioned using a LocaleChangeInterceptor bean as well as beans for MessageSource and LocaleResolver in your main class, but another article said Spring Boot doesn't require that. I tried it anyway with no difference. These are the functions I used:

@Bean
open fun localeResolver(): LocaleResolver {
    val slr = SessionLocaleResolver()
    slr.setDefaultLocale(Locale.US)
    return slr
}

@Bean
open fun localeChangeInterceptor(): LocaleChangeInterceptor {
    val localeChangeInterceptor = LocaleChangeInterceptor()
    localeChangeInterceptor.paramName = "locale"
    return localeChangeInterceptor
}

@Bean
open fun messageSource(): ResourceBundleMessageSource {
    val source = ResourceBundleMessageSource()
    source.setBasenames("messages/messages")
    source.setDefaultEncoding("UTF-8")
    return source
}

Any suggestions on what to try next other than capturing the locale manually and making it a parameter in every function that gets called by the controller? Thanks!

Upvotes: 1

Views: 2113

Answers (1)

irotsoma
irotsoma

Reputation: 705

OK, looks like the missing piece was implementing a WebMvcConfigurerAdapter, setting up a SessionLocaleResolver bean, and overriding the addInterceptors function to manually add my LocaleChangeInterceptor. I used a separate Configuration class to do this.

@Configuration
open class CustomWebMvcConfigurerAdapter : WebMvcConfigurerAdapter() {

    //internationalization beans
    @Bean
    open fun localeResolver(): LocaleResolver {
        val slr = SessionLocaleResolver()
        slr.setDefaultLocale(Locale.US)
        return slr
    }

    @Bean
    open fun localeChangeInterceptor(): LocaleChangeInterceptor {
        val localeChangeInterceptor = LocaleChangeInterceptor()
        localeChangeInterceptor.paramName = "locale"
        return localeChangeInterceptor
    }

    override fun addInterceptors(registry: InterceptorRegistry?) {
        registry?.addInterceptor(localeChangeInterceptor())
        super.addInterceptors(registry)
    }
}

I guess I misunderstood, thinking that Spring Boot handled the LocaleChangeInterceptor on it's own if you created the proper bean, but I guess you have to still override a WebMvcConfigurerAdapter and force the interceptor in there. If I've missed something and someone has a cleaner solution, I'd be happy to give you the accepted answer since what I'm doing here just feels like a messy workaround.

Upvotes: 1

Related Questions