Stephane
Stephane

Reputation: 12790

Set a default locale in the configuration for later use in an integration test

I have an integration test that loads up the main web configuration of the application.

The integration test class is configured with the annotations:

@SpringBootTest(classes = { ApplicationConfiguration.class, WebConfiguration.class })
@RunWith(SpringRunner.class)
@WebAppConfiguration

In this test, the default application locale is retrieved:

@Test
public void testRuntimeException() throws Exception {
    Locale defaultLocale = Locale.getDefault();
    // defaultLocale = LocaleContextHolder.getLocale();
    this.mockMvc.perform(
            get("/error/rte").headers(httpHeaders)
            .accept(MediaType.APPLICATION_JSON)
        )
        .andExpect(status().isInternalServerError())
        .andExpect(jsonPath("$.message").value(localizeErrorMessage("error.rte")))
        .andReturn();
}

The above two ways of retrieving the locale, both return the fr_FR locale.

I suspect it is because my (Linux) OS user has this fr_FR has locale.

I would like my application to ignore the OS user locale and so I tried to specify a default locale in the configuration of the application.

I tried using eihttps://jira.spring.io/browse/SPR-16775ther of these locale resolvers:

@Bean
public LocaleResolver localeResolver() {
    CookieLocaleResolver localeResolver = new CookieLocaleResolver();
    localeResolver.setDefaultLocale(Locale.ENGLISH);
    return localeResolver;
}

@Bean
public LocaleResolver localeResolver() {
    SessionLocaleResolver localeResolver = new SessionLocaleResolver();
    localeResolver.setDefaultLocale(Locale.ENGLISH);
    return localeResolver;
}

When using them the test always returns the fr_FR locale.

On top of that, when the locale is set in the request header, it is still being ignored by the controller and the default locale is sent in the response, with the following test (that contains two different ways of setting the request header locale) failing:

httpHeaders.add(HttpHeaders.ACCEPT_LANGUAGE, Locale.FRENCH.toLanguageTag());
this.mockMvc.perform(
        get("/error/npe").headers(httpHeaders).locale(Locale.FRENCH)
        .accept(MediaType.APPLICATION_JSON))
        .andDo(print()
    )
    .andExpect(status().isInternalServerError())
    .andExpect(jsonPath("$.message").value(localizeErrorMessage("error.npe", Locale.FRENCH)))
    .andReturn();

I'm using Spring Boot 2.0.3.RELEASE.

UPDATE: To have the request language header noticed by the server, I had to use the AcceptHeaderLocaleResolver resolver, as the SessionLocaleResolver and the CookieLocaleResolver resolvers would not notice the request language header.

So my configuration looks like:

private static final List<Locale> SUPPORTED_LOCALES = Arrays.asList(Locale.ENGLISH, Locale.FRENCH);

@Bean
public LocaleResolver localeResolver() {
    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    localeResolver.setSupportedLocales(SUPPORTED_LOCALES);
    localeResolver.setDefaultLocale(Locale.ENGLISH);
    return localeResolver;
}

I also have in the configuration a locale interceptor:

// The locale interceptor provides a way to switch the language in any page
// just by passing the lang=’en’, lang=’fr’, and so on to the url
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
    LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
    localeChangeInterceptor.setParamName(LOCALE_LANGUAGE_PARAM);
    return localeChangeInterceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
    registry.addInterceptor(webContentInterceptor());
}

But using the AcceptHeaderLocaleResolver means that the url lang parameter is not noticed, so I cannot use it in the requests. The above interceptor is useless. Only the header can be used for now.

UPDATE: I noticed that using Locale.getDefault() ignores the default locale configured in the localeResolver bean. To get this default locale, I have to use:

@Autowired
private AcceptHeaderLocaleResolver localeResolver;

localeResolver.getDefaultLocale();

UPDATE: The locale interceptor seems to have an open issue at this time.

Upvotes: 0

Views: 7401

Answers (1)

Jesus
Jesus

Reputation: 155

Stephane,

I had the same problem, and in my search for a solution, I found the following: Solution to resolve set default locale in spring boot

Insert in the src/main/resources/application.properties file, the following code and edit the locale:

#setting to default locale
spring.mvc.locale=pt_BR
#force locale resolver to spring boot reconized your settings
spring.mvc.locale-resolver=fixed

This works for me and surprises me for its simplicity. I hope it helps you!

Best regards! Jesus

Upvotes: 4

Related Questions