SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)

国际化是什么

听起来很高大上的国际化 其实就是通过浏览器的语言信息来动态显示国际化效果
通俗来说 就是 点击中文按钮的时候显示中文 点击英文按钮的时候显示英文(当然还支持其它语言

国际化的实现步骤:

  • 1)、编写国际化配置文件
  • 2)、使用ResourceBundleMessageSource管理国际化资源文件
  • 3)、在页面取出国际化内容

在SpringBoot内部已经实现了第2步和第3步 它的底层已经配置好了 因此 只须编写国际化配置文件即可

一、编写国际化配置文件

编写国际化配置文件 就是抽取页面需要显示的国际化消息
通俗来说 就是将要"翻译"的文字提取出来

在resources资源目录下创建一个包 用于存放国际化配置文件
然后创建配置文件login.properties
命名格式:页面名_语言代码_国家代码.properties

当IDEA识别到 就会自动切换到国际化视图
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第1张图片
这样的话 可直接右键创建国际化配置文件
点击右侧的加号(+)
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第2张图片
输入语言代码_国家代码即可 会自动生成配置文件
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第3张图片
然后可在配置文件左下角点击Resource Bundle切换视图
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第4张图片
点击左上角的加号(+)添加一套语言配置
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第5张图片
如此照葫芦画瓢 配置好全部需要转换的语言部分
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第6张图片

二、自动国际化

SpringBoot已经自动配置好了管理国际化资源文件的组件

语言资源自动配置类的底层代码是这样的:

@ConfigurationProperties(prefix = "spring.messages")
public class MessageSourceAutoConfiguration {
    
    /**
	 * Comma-separated list of basenames (essentially a fully-qualified classpath
	 * location), each following the ResourceBundle convention with relaxed support for
	 * slash based locations. If it doesn't contain a package qualifier (such as
	 * "org.mypackage"), it will be resolved from the classpath root.
	 */
	private String basename = "messages";  
    ...
}

因此 可以看见 配置文件默认的基础名为messages
基础名就是配置文件去掉例如zh_CN的名称
可用spring.messages来配置
基础名可包含包名 若不包含 则从类路径下寻找

然后去配置文件中配置
例:spring.messages.basename=i18n.login
该配置路径的意义为 从i18n包下寻找基础名为login的配置文件
目的是为了让SpringBoot能找到我们配置的国际化配置文件

三、在页面获取国际化后的值

Thymeleaf的#{}语法就是用来获取国际化信息的
因此 可很方便地获取到国际化后的值

用th:表达式进行替换
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第7张图片
如此 即可实现自动国际化

乱码问题:

IDEA中默认不会将中文转为ASCII码 因此 会导致乱码问题
在设置中 选择File Encoding 然后勾选自动转换ASCII码
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第8张图片
这样配置 默认根据的是浏览器的语言
浏览器用什么语言 就自动识别 然后作为默认语言
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第9张图片
SpringBoot专题学习Part16:SpringBoot实现国际化语言切换功能(i18n)_第10张图片

当然 还可以手动点击按钮切换语言

这个功能在一些外贸网站上比较常见

原理:
国际化的Locale区域信息对象里面有个LocaleResolver组件 用于获取区域信息对象

SpringBoot默认也配置了区域信息解析器
底层代码:

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
    if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
        return new FixedLocaleResolver(this.mvcProperties.getLocale());
    }
    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
    return localeResolver;
}

意思就是 当指定固定的区域解析器时 就使用固定的 否则使用AcceptHeaderLocaleResolver
而AcceptHeaderLocaleResolver是从浏览器的请求头中获取Locale信息 然后进行国际化
因为 浏览器在发送请求时 请求头中会带有一个Accept Language字段 里面有浏览器的默认语言
AcceptHeaderLocaleResolver就是通过这个来识别浏览器默认语言的

因此 只需将LocaleResolver替换即可

在前端 需要在切换按钮的链接上携带区域信息

<a class="btn btn-sm" th:href="@{/index.html(language=zh_CN)}">中文a>
<a class="btn btn-sm" th:href="@{/index.html(language=en_US)}">Englisha>

当点击切换语言链接的时候 就会带上语言参数来发送请求

这样 URL后面就能携带区域信息了:

http://ip:端口/XXXX/index.html?language=zh_CN

然后 在后端 须创建一个自己的区域解析器类 实现LocaleResolver接口
直接上代码:

public class MyLocaleResolver implements LocaleResolver {

    // 解析区域信息
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        // 从URL的参数中获取区域信息
        String language = request.getParameter("language");
        // 区域信息默认用系统识别的
        Locale locale=Locale.getDefault();
        // 若获取的区域参数不为空 即 URL带有区域信息
        if (!StringUtils.isEmpty(language))
        {
            // 根据中间的下划线分隔成两部分
            String[] s = language.split("_");
            locale=new Locale(s[0],s[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

    }
}

然后在自己写的配置类中添加自己的区域解析器类到Spring容器中(记得加@Bean注解)

@Bean
public LocaleResolver localeResolver()
{
        // 直接返回自己配置的区域解析器
        return new MyLocaleResolver();
}

如此配置 自己的区域解析器就能正常工作了 会替代掉SpringBoot自带的区域解析器
最终达到的效果就是 当URL带有区域信息 则使用指定的语言 当URL不带有区域信息 则自动根据浏览器语言进行识别


你可能感兴趣的:(框架)