How to configure i18n in Spring boot 2 + Webflux + Thymeleaf?

后端 未结 3 1817
清酒与你
清酒与你 2021-02-19 11:10

I just start a new project based on Spring boot 2 + Webflux. On upgrading version of spring boot and replace spring-boot-starter-web with spring-boot-starter-

3条回答
  •  面向向阳花
    2021-02-19 11:33

    Just add a WebFilter that sets the Accept-Language header from the value of a query parameter. The following example gets the language from the language query parameter on URIs like http://localhost:8080/examples?language=es:

    import org.springframework.boot.context.event.ApplicationReadyEvent;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.event.EventListener;
    import org.springframework.http.server.reactive.ServerHttpRequest;
    import org.springframework.stereotype.Component;
    import org.springframework.util.MultiValueMap;
    import org.springframework.web.server.ServerWebExchange;
    import org.springframework.web.server.WebFilter;
    import org.springframework.web.server.WebFilterChain;
    import org.springframework.web.server.adapter.DefaultServerWebExchange;
    import org.springframework.web.server.adapter.HttpWebHandlerAdapter;
    import reactor.core.publisher.Mono;
    
    import static org.springframework.util.StringUtils.isEmpty;
    
    @Component
    public class LanguageQueryParameterWebFilter implements WebFilter {
    
        private final ApplicationContext applicationContext;
    
        private HttpWebHandlerAdapter httpWebHandlerAdapter;
    
        public LanguageQueryParameterWebFilter(final ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }
    
        @EventListener(ApplicationReadyEvent.class)
        public void loadHttpHandler() {
            this.httpWebHandlerAdapter = applicationContext.getBean(HttpWebHandlerAdapter.class);
        }
    
        @Override
        public Mono filter(final ServerWebExchange exchange, final WebFilterChain chain) {
            final ServerHttpRequest request = exchange.getRequest();
            final MultiValueMap queryParams = request.getQueryParams();
            final String languageValue = queryParams.getFirst("language");
    
            final ServerWebExchange localizedExchange = getServerWebExchange(languageValue, exchange);
            return chain.filter(localizedExchange);
        }
    
        private ServerWebExchange getServerWebExchange(final String languageValue, final ServerWebExchange exchange) {
            return isEmpty(languageValue)
                    ? exchange
                    : getLocalizedServerWebExchange(languageValue, exchange);
        }
    
        private ServerWebExchange getLocalizedServerWebExchange(final String languageValue, final ServerWebExchange exchange) {
            final ServerHttpRequest httpRequest = exchange.getRequest()
                    .mutate()
                    .headers(httpHeaders -> httpHeaders.set("Accept-Language", languageValue))
                    .build();
    
            return new DefaultServerWebExchange(httpRequest, exchange.getResponse(),
                    httpWebHandlerAdapter.getSessionManager(), httpWebHandlerAdapter.getCodecConfigurer(),
                    httpWebHandlerAdapter.getLocaleContextResolver());
        }
    }
    

    It uses @EventListener(ApplicationReadyEvent.class) in order to avoid cyclic dependencies.

    Feel free to test it and provide feedback on this POC.

提交回复
热议问题