这篇技术文章中,我们将看到如何在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
请到 此处 下载项目。