这篇技术文章中,我们将看到如何在Spring Webflux应用程序中使用不同语言以及 Thymeleaf 模板框架。
让我们使用这个命令创建一个新项目:
spring init --dependencies=webflux --build=gradle --language=java spring-webflux-internationalization
这是生成的build.gradle文件:
buildscript { ext { springBootVersion = '2.1.2.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' group = 'com.jos.dem.spring.webflux.internationalization' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation('org.springframework.boot:spring-boot-starter-webflux') testImplementation('org.springframework.boot:spring-boot-starter-test') testImplementation('io.projectreactor:reactor-test') }
然后将Thymeleaf依赖项添加到您的build.gradle文件中:
implementation('org.thymeleaf:thymeleaf-spring5:3.0.11.RELEASE')
Spring Boot有一个用于解析消息的策略接口,支持此类消息的国际化。
@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasenames("i18n/messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; }
现在是配置模板解析器,模板引擎和视图解析器的时候了,因为我们需要将Thymeleaf配置为html模板。
@Bean public ITemplateResolver thymeleafTemplateResolver() { final SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(this.context); resolver.setPrefix("classpath:templates/"); resolver.setSuffix(".html"); resolver.setTemplateMode(TemplateMode.HTML); resolver.setCacheable(false); resolver.setCheckExistence(false); return resolver; } @Bean public ISpringWebFluxTemplateEngine thymeleafTemplateEngine() { SpringWebFluxTemplateEngine templateEngine = new SpringWebFluxTemplateEngine(); templateEngine.setTemplateResolver(thymeleafTemplateResolver()); return templateEngine; } @Bean public ThymeleafReactiveViewResolver thymeleafReactiveViewResolver() { ThymeleafReactiveViewResolver viewResolver = new ThymeleafReactiveViewResolver(); viewResolver.setTemplateEngine(thymeleafTemplateEngine()); return viewResolver; } @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.viewResolver(thymeleafReactiveViewResolver()); }
这是完整的完整Web配置:
@Configuration @EnableWebFlux public class WebConfig implements ApplicationContextAware, WebFluxConfigurer { private ApplicationContext context; @Override public void setApplicationContext(ApplicationContext context) { this.context = context; } @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasenames("i18n/messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } @Bean public ITemplateResolver thymeleafTemplateResolver() { final SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); resolver.setApplicationContext(this.context); resolver.setPrefix("classpath:templates/"); resolver.setSuffix(".html"); resolver.setTemplateMode(TemplateMode.HTML); resolver.setCacheable(false); resolver.setCheckExistence(false); return resolver; } @Bean public ISpringWebFluxTemplateEngine thymeleafTemplateEngine() { SpringWebFluxTemplateEngine templateEngine = new SpringWebFluxTemplateEngine(); templateEngine.setTemplateResolver(thymeleafTemplateResolver()); return templateEngine; } @Bean public ThymeleafReactiveViewResolver thymeleafReactiveViewResolver() { ThymeleafReactiveViewResolver viewResolver = new ThymeleafReactiveViewResolver(); viewResolver.setTemplateEngine(thymeleafTemplateEngine()); return viewResolver; } @Override public void configureViewResolvers(ViewResolverRegistry registry) { registry.viewResolver(thymeleafReactiveViewResolver()); } }
如您所见SpringResourceTemplateResolver,负责设置我们的模板文件路径和扩展名。在这种情况下,将定义一个index.html带有hello world消息的网页。
<html> <head> <meta charset="utf-8"> <title>Internationalization with Spring Webflux</title> </head> <body></body> </html>
ResourceBundleMessageSource为每种支持的语言定义消息资源路径。在这种情况下,我们将定义messages.properties为英语。
user.hello=Hello from internationalization!
messages_es.properties为西班牙:
user.hello=¡Hola Internacionalización!
下一步是告诉Spring使用Locale解析器。所以我们需要添加一个扩展自DelegatingWebFluxConfiguration定义的配置类LocaleContextResolver。
@Configuration public class LocaleSupportConfig extends DelegatingWebFluxConfiguration { @Override protected LocaleContextResolver createLocaleContextResolver() { return new LocaleResolver(); } }
这是我们的语言环境解析器:
public class LocaleResolver implements LocaleContextResolver { @Override public LocaleContext resolveLocaleContext(ServerWebExchange exchange) { String language = exchange.getRequest().getHeaders().getFirst("Accept-Language"); Locale targetLocale = Locale.getDefault(); if (language != null && !language.isEmpty()) { targetLocale = Locale.forLanguageTag(language); } return new SimpleLocaleContext(targetLocale); } @Override public void setLocaleContext(ServerWebExchange exchange, LocaleContext localeContext) { throw new UnsupportedOperationException("Not Supported"); } }
就是这样,我们在客户请求的标题中阅读语言支持,这样我们就可以向客户显示正确的消息,无论是使用英语还是西班牙语。最后,这是我们的控制器来呈现索引网页。
@Controller public class InternationalizationController { @GetMapping("/") public String index() { return "index"; } }
要运行项目:
gradle bootRun
请到 此处 下载项目。