准备工作

在某些网页中,是要求中英文可以相互切换的,因此需要学习Java的国际化编码。
首先需要确保编码都是UTF-8:
image.png
接着在resources资源目录下新建i18n文件夹,然后建立一个login.properties文件,还有一个login_zh_CN.properties;发现IDEA自动识别了我们要做国际化操作:
image.png
然后还需要新建其它文件:
image.png

弹出如下页面,再添加一个英文的;
页面国际化 - 图4

页面国际化 - 图5

接下来,我们就来编写配置,我们可以看到idea下面有另外一个视图;
页面国际化 - 图6
这个视图我们点击 + 号就可以直接添加属性了;我们新建一个login.tip,可以看到边上有三个文件框可以输入
image.png

我们添加一下首页的内容:
image.png

然后依次添加其他页面内容即可:

页面国际化 - 图9

最后,需要到核心配置文件里面配置:

  1. spring:
  2. messages:
  3. basename: i18n.login

编写组件类

public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest req) {
        String lang = req.getParameter("lang");
        Locale locale = Locale.getDefault();
        if (!StringUtils.isEmpty(lang)) {
            String[] split = lang.split("_");
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

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

    }
}

其中需要前端的lang参数,参数值值得形式是“国家-地区名”,如:中国大陆zh-CN(中文),美国en_US(英文)等等
然后编写前端页面:


<form class="form-signin" th:action="@{/user/login}">
    <img class="mb-4" th:src="@{../img/bootstrap-solid.svg}" alt="" width="72" height="72">
    <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
    <span style="font-size:10px;color: red" th:text="${errorMsg}"></span>
    <label class="sr-only">Username</label>
    <input name="username" type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
    <label class="sr-only">Password</label>
    <input name="password" type="password" class="form-control" th:placeholder="#{login.pwd}" required="">
    <div class="checkbox mb-3">
    <label>
       <input type="checkbox" value="remember-me" th:text="#{login.remember}">
   </label>
     </div>
    <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
    <p class="mt-5 mb-3 text-muted">© 2017-2018</p>
    <a class="btn btn-sm" th:href="@{/index.html(lang='zh_CN')}">中文</a>
    <a class="btn btn-sm" th:href="@{/index.html(lang='en_US')}">English</a>
</form>

其中:

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

就是需的参数lang,整体页面效果如下:
image.png
因此点击“中文”传“zh_CN”,点击“English”传“en_US”
最后需要把组件类注册到Spring中:

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    /**
     * 注册自定义自定义的LocaleResolver
     */
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
}

原理探究

在Spring中有一个国际化的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;
}

LocaleResolver类里面出现的AcceptHeaderLocaleResolver这个类中有一个方法:

public Locale resolveLocale(HttpServletRequest request) {
    Locale defaultLocale = this.getDefaultLocale();
    // 默认的就是根据请求头带来的区域信息获取Locale进行国际化
    if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
        return defaultLocale;
    } else {
        Locale requestLocale = request.getLocale();
        List<Locale> supportedLocales = this.getSupportedLocales();
        if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
            Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
            if (supportedLocale != null) {
                return supportedLocale;
            } else {
                return defaultLocale != null ? defaultLocale : requestLocale;
            }
        } else {
            return requestLocale;
        }
    }
}

那假如我们现在想点击链接让我们的国际化资源生效,就需要让我们自己的Locale生效,因此需要实现LocaleResolver接口的编写自己的组件类MyLocaleResolver并注册到Spring中。

效果展示

image.png
切换中文:
image.png