Search code examples
hibernate-validator

How to bootstrap custom locale resolver to validator in a quarkus rest api application


I've created a custom locale resolver for the purpose of internationalization of quarkus rest application. Since I'm new to quarkus, could you please let me know where should I write the following bootstrap code in the application,

ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() .localeResolver(customlocaleresolver) .locales(Locale.GERMAN, Locale.FRENCH, Locale.ITALIAN) .defaultLocale(Locale.ENGLISH) .buildValidatorFactory(); return validatorFactory.getValidator(); Also, how should I make controller class to know that locale has to be resolved before sending the response.Any help is greatly appreciated. Thanks I referred this link for internationalization - https://in.relation.to/2020/01/23/hibernate-validator-6-1-1-released/

Adding the custom locale resolver, getting null for httpheader from resteasycontext.

public class ResteasyContextLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolve(LocaleResolverContext context) {
        Optional<List<Locale.LanguageRange>> localePriorities = getAcceptableLanguages();
        if (!localePriorities.isPresent()) {
            return context.getDefaultLocale();
        }

        List<Locale> resolvedLocales = Locale.filter(localePriorities.get(), context.getSupportedLocales());
        if (resolvedLocales.size() > 0) {
            return resolvedLocales.get(0);
        }

        return context.getDefaultLocale();
    }

    private Optional<List<Locale.LanguageRange>> getAcceptableLanguages() {
        HttpHeaders httpHeaders = ResteasyContext.getContextData(HttpHeaders.class);
        if (httpHeaders != null) {
            List<String> acceptLanguageList = httpHeaders.getRequestHeader("Accept-Language");
            if (acceptLanguageList != null && !acceptLanguageList.isEmpty()) {
                return Optional.of(Locale.LanguageRange.parse(acceptLanguageList.get(0)));
            }
        }

        return Optional.empty();
    }
}

Solution

  • This is documented in the Hibernate Validator guide for Quarkus:

    You can configure this behavior by adding the following configuration in your application.properties:

    # The default locale to use
    quarkus.default-locale=fr-FR
    

    If you are using RESTEasy Reactive, in the context of a JAX-RS endpoint, Hibernate Validator will automatically resolve the optimal locale to use from the Accept-Language HTTP header, provided the supported locales have been properly specified in the application.properties:

    # The list of all the supported locales
    quarkus.locales=en-US,es-ES,fr-FR
    

    If the built-in feature that resolves the locale from the Accept-Language HTTP header suits your needs, then you do not need a custom locale resolver.

    If that built-in feature isn't enough for some reason, you can declare your locale resolver as a CDI bean and it should get automatically picked up:

    @ApplicationScoped
    public class MyLocaleResolver implements LocaleResolver {
       // ...
    }
    

    If that doesn't work for some reason, you can probably use a ValidatorFactoryCustomizer:

    @ApplicationScoped
    public class MyValidatorFactoryCustomizer implements ValidatorFactoryCustomizer {
    
        @Override
        public void customize(BaseHibernateValidatorConfiguration<?> configuration) {
            configuration.localeResolver(customlocaleresolver);
        }
    }
    

    That last solution will, however, completely override any built-in locale resolver: the Accept-Language HTTP header will get completely ignored.