springboot i18n 国际化-元一软件
2026/9/8 19:33:42 网站建设 项目流程

创建项目

pom.xml中添加webfreemarkerstater 依赖。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency>

配置

定义国际化资源文件

通常我们会把项目中需要国际化的内容定义在不同的 properties 文件中,通过 properties 文件名的后缀来表示资源的语言国别

resources目录下创建i18n目录,用于存放国际化资源文件。接着,在i18n目录中创建如下 3 个 properties 文件,如下:

软件

message.properties

# message.properties 的内容# 空着就行

message_en_US.properties

# message_en_US.properties 的内容# 英文login.username=USERNAMElogin.password=PASSWORD

message_zh_CN.properties

# message_zh_CN.properties 的内容# 中文login.username=用户名login.password=密 码

如上,除了第 1 个空文件外,分别在 2 个资源文件中指定了不同语言的国际化内容。

  • message_en_US.properties则表示英文资源,en表示英文,US表示美国。
  • message_zh_CN.properties表示是中文资源,其中zh表示中文,CN表示中国。

按照这个格式,你可以配置多个其他语言和国别的资源。

社会科学

  • message_en_GB.properties:英国、英语
  • message_ko_KR.properties:韩文、韩国

也可以不指定国别,仅指定语言,如:message_en.properties,表示英语,但不分国别(美国、英国、加拿大都说英语)。

注意,properties 文件的编码一定要是 UTF-8!

message.properties文件一定要存在,哪怕是空的。否则可能会在运行时遇到如下异常。

org.springframework.context.NoSuchMessageException: No message found under code'...'forlocale'...'.

配置国际化

application.yaml中添加如下配置:

spring: messages:# 指定资源文件夹以及文件的前缀basename: i18n/message freemarker:# 暴露 spring 提供的宏expose-spring-macro-helpers:true# 模板的加载路径template-loader-path: classpath:/templates/

spring.messages.basename指定了国际化资源文件的 “前缀”,也就是上文国际化资源文件所在的目录和基本名称。

Java(编程语言)

spring.freemarker则是整合 Freemarker 模板引擎的配置。expose-spring-macro-helpers设置为true暴露了 spring 提供的宏,我们会通过这个宏定义的指令来在模板上渲染国际化资源。template-loader-path配置则是指定了模板引擎的目录(关于 Spring Boot 整合 Freemarker 的更多细节你可以参考 这篇文章)。

创建 LocaleResolver Bean

LocaleResolver接口用于解析客户端的语言环境,默认它提供了如下实现:

  • CookieLocaleResolver:从 Cookie 解析客户端语言。
  • FixedLocaleResolver:固定使用 JVM 的默认语言,不支持更改。
  • SessionLocaleResolver:从 Session 解析客户端语言。

这里我们使用CookieLocaleResolver,也就是说在用户选择了语言后,把语言信息存储在客户端浏览器的 Cookie 中,这样的话服务器就不用维护状态了。

创建I18nConfiguration配置类,如下:

package cn.springdoc.demo.configuration;importjava.util.Locale;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.LocaleResolver;importorg.springframework.web.servlet.i18n.CookieLocaleResolver;@Configuration public class I18nConfiguration{/** * LocaleResolver 用于解析客户端的语言环境 * @return */ @Bean public LocaleResolverlocaleResolver(){// 创建 CookieLocaleResolver,指定 cookie 名称为 _lang CookieLocaleResolver cookieLocaleResolver=new CookieLocaleResolver("_lang");// 设置默认的语言,国别。 Locale.CHINA 也就是 zn_CN cookieLocaleResolver.setDefaultLocale(Locale.CHINA);// 不允许 JS 读写此 Cookie cookieLocaleResolver.setCookieHttpOnly(true);//... 其他设置returncookieLocaleResolver;}}

通过CookieLocaleResolver构造函数指定 Cookie 的名称,默认是org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE

setDefaultLocale方法设置默认的语言。在客户端选择的语言不支持,或者客户端未选择语言的情况下,默认使用的国际化资源。这里设置为Locale.CHINA,也就是zh_CN

还可以设置关于 Cookie 的一些属性,如:sameSitemaxAgedomainpathsecure等等。这里仅设置了httpOnly属性,表示禁止 JS 读写这个 Cookie。

计算机驱动器和存储设备

创建 LocaleChangeInterceptor Bean

LocaleChangeInterceptor拦截器,用于拦截用户的请求。根据用户请求参数来设置语言环境。

创建MvcConfiguration配置类,实现WebMvcConfigurer接口:

package cn.springdoc.demo.configuration;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.http.HttpMethod;importorg.springframework.web.servlet.config.annotation.InterceptorRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;importorg.springframework.web.servlet.i18n.LocaleChangeInterceptor;@Configuration public class MvcConfiguration implements WebMvcConfigurer{@Override public void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(this.localeChangeInterceptor()).addPathPatterns("/**");}@Bean public LocaleChangeInterceptorlocaleChangeInterceptor(){LocaleChangeInterceptor interceptor=new LocaleChangeInterceptor();// 受 GET 请求 interceptor.setHttpMethods(HttpMethod.GET.name());// 传递客户端语言的查询参数 interceptor.setParamName("_lang");// 忽略客户端非法的参数 interceptor.setIgnoreInvalidLocale(true);returninterceptor;}}

创建LocaleChangeInterceptor拦截器实例 Bean。通过setHttpMethods方法指定要拦截的请求方法。setParamName方法设置一个参数名称。客户端通过这个参数传递所选择的语言。setIgnoreInvalidLocale方法表示是否要忽略客户端传递的非法参数值。

软件

最后通过addInterceptors配置拦截器,拦截所有请求。

创建模板引擎

resources目录下创建templates目录,用于存放模板引擎(上述配置spring.freemarker.template-loader-path定义的值)。

接着,在templates下创建login.ftlh模板引擎文件,内容如下。

<#-- 导入 spring 的宏 --><#import "/spring.ftl" as spring/><!DOCTYPE html><html><head><metacharset="UTF-8"><title>Login</title></head><body><form><#-- 通过 spring.message 指令加载国际化资源 --><@spring.messagecode='login.username'/><inputname="username"/><br/><@spring.messagecode='login.password'/><inputname="password"type="password"/></form></body></html>

首先在最顶部通过<#import "/spring.ftl" as spring/>导入 Spring 预定义的宏/spring.ftl,命名为spring。这个宏定义了大量的工具指令。

社会科学

在模板中,通过<@spring.message code='login.username'/>调用spring宏中的message指令,其中code参数就是在国际化资源文件中定义的 KEY。该指令会根据当前请求所设置的语言环境,自动从对应语言的资源文件中根据 KEY 读取配置值。

最后,创建渲染login模板的 Controller:

package cn.springdoc.demo.web.controller;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.servlet.ModelAndView;@Controller @RequestMapping public class LoginController{@GetMapping("/login")public ModelAndViewlogin(){returnnew ModelAndView("login");}}

测试

启动应用后,用浏览器访问http://localhost:8080/login

由于第一次访问,且未指定使用的语言。根据LocaleResolver配置,默认使用zh_CN,所以你会看到中文表单名称。

Java(编程语言)

接着,尝试添加 “语言参数”。访问http://localhost:8080/login?_lang=en_US

这次,传递了一个_lang=en_US参数,LocaleChangeInterceptor会拦截到此请求,并把当前请求环境设置为en_US。所以,能看到英文表单名称。

_lang参数的值要符合:[语言]_[国别]。格式

因为使用了 Cookie,所以只要你没有再次使用_lang=en_US参数来切换不同的语言,则所有请求都会被解析为en_US语言。

在代码中获取到国际化配置

除了模板引擎,我们也可以在代码中通过MessageSourceBean 来根据Local获取不同的国际化消息值。

数据管理

例如,在上述LoginController中注入MessageSource

static final Logger log=LoggerFactory.getLogger(LoginController.class);// 注入 MessageSource @Autowired private MessageSource messageSource;@GetMapping("/login")public ModelAndViewlogin(){// 当前请求的语言环境 Locale locale=LocaleContextHolder.getLocale();// 根据请求的语言环境来获取国际化配置信息 String loginUserName=messageSource.getMessage("login.username", null, locale);log.info("Local={}, loginUserName={}", locale, loginUserName);returnnew ModelAndView("login");}

首先,注入MessageSource

在 Controller 方法中通过LocaleContextHolder获取到当前请求所设置的语言环境Locale对象。再使用MessageSource通过这个Locale对象获取对应的国际化配置信息。

编程

修改后,重启应用。再次访问http://localhost:8080/login,服务端输出日志如下:

INFO8368---[nio-8080-exec-2]c.s.demo.web.controller.LoginController:Local=en_US,loginUserName=USERNAME

如上,成功读取到了国际化的配置信息。因为上次请求使用的是en_US,由于 Cookie 还在,所以这次请求的语言环境也同样是en_US

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询