Spring Boot入门样例-170-i18n国际化多语言切换

Spring Boot入门样例-170-i18n国际化多语言切换

当网站有多个国家用户访问时,如何让他们切换自己熟悉的语言。本demo演示在Spring Boot中国际化。

前言

本Spring Boot入门样例准备工作参考:

模板渲染样例请参考,Spring Boot入门样例-060-thymeleaf 本demo是在该模板基础上扩展的

pox.xml

必要的依赖如下,具体参见该项目的pox.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>

        <dependency><!--jQuery国际化插件-->
            <groupId>org.webjars.bower</groupId>
            <artifactId>jquery-i18n-properties</artifactId>
            <version>1.2.7</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

配置文件

resources/application.yml配置内容 basename配置语言路径在resource/messages/messages.properties 等文件

spring:
  messages:
    basename: i18n/messages
    encoding: UTF-8
    cache-duration: 3600
  thymeleaf:
    cache: false
    servlet:
      content-type: text/html
    mode: HTML
    encoding: UTF-8

代码解析

该项目有很多目录,分别说明如下:

  • config目录为控制器文件
  • controller目录为控制器文件
  • entity目录为实体目录,对应表格中的字段(本样例不查询数据库)
  • resource/messages语言文件路径
  • resources/templates对应模板文件路径
  • resources/static静态文件路径,包括css和images图片

以下解释和国际化相关的文件

LocaleConfig.java 为,配置默认语言为英语 其中路径参数lang表示切换语言的参数名

@Configuration
public class LocaleConfig {
    /**
     * 默认解析器 其中locale表示默认语言
     * @author funsonli
     */
    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        // 默认语言为英语
        localeResolver.setDefaultLocale(Locale.US);
        return localeResolver;
    }

    /**
     * 默认拦截器 其中lang表示切换语言的参数名
     * @author funsonli
     */
    @Bean
    public WebMvcConfigurer localeInterceptor() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
                localeInterceptor.setParamName("lang");
                registry.addInterceptor(localeInterceptor);
            }
        };
    }
}

SiteController.java 如下

@Controller
public class SiteController {

    @GetMapping({"", "/", "index"})
    public String index(HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute("user");
        if (user  == null) {
            return "redirect:/login";
        }
        request.setAttribute("user", user);
        return "site/index";
    }

    @GetMapping("/login")
    public String login() {
        return "site/login";
    }

    @PostMapping("/login")
    public String save(@ModelAttribute User modelAttribute, BindingResult result, HttpServletRequest request) {
        if (result.hasErrors()) {
            return "binding error";
        }
        request.getSession().setAttribute("user", modelAttribute);
        return "redirect:/";
    }
}

  1. index方法先判断是否登录,否则跳转login
  2. get的login方法显示resources/templates/site/login.html文件,该文件会引入resources/templates/common/head.html,以及使用resources/static中的css和图片文件
  3. 登录后显示resources/templates/site/index.html中内容

head.html 和语言有关的变量使用 #{xxx}来读取,不是${xxx}来读取

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="header">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>欢迎使用Spring Boot入门样例之thymeleaf</title>
    <link type="text/css" rel="stylesheet" href="/css/style.css" />
    <script th:src="@{/webjars/jquery/3.3.1/jquery.min.js}"></script>
    <script th:src="@{/webjars/jquery-i18n-properties/jquery.i18n.properties.min.js}"></script>
    <script th:inline="javascript">
        //获取应用路径
        var ROOT = [[${#servletContext.contextPath}]];

        //获取默认语言
        var LANG_COUNTRY = [[${#locale.language+'_'+#locale.country}]];
    </script>
</head>
</html>

index.html 在script中通过在参数后加 ?lang=xxx 来切换语音

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<header th:replace="~{common/head :: header}"></header>
<body>
<div class="header">
    <a href="/"><img src="/images/logo.png"></a><span th:text="#{spring_boot}">
</div>
<div class="content">
    <select id="locale">
        <option value="zh_CN">中文简体</option>
        <option value="en_US">English</option>
    </select>

    <span th:text="#{welcome}"></span><span th:text="${user.name}"></span>
</div>
<script th:inline="javascript">
    //选中语言
    $("#locale").find('option[value="' + LANG_COUNTRY + '"]').attr('selected', true);
    //切换语言
    $("#locale").change(function () {
        $.get(ROOT + '/?lang=' + $("#locale").val(), function () {
            location.reload();
        });
    });
</script>
</body>
</html>

login.html 在script中通过在参数后加 ?lang=xxx 来切换语音

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<header th:replace="~{common/head :: header}"></header>
<body>
<div class="header">
    <a href="/"><img src="/images/logo.png"></a><span th:text="#{spring_boot}">
</div>

<div class="content">
    <select id="locale">
        <option value="zh_CN">中文简体</option>
        <option value="en_US">English</option>
    </select>
    <form action="/login" method="post">
        <input type="text" name="name" th:placeholder="#{user.name}"/><br>
        <input type="password" name="password" th:placeholder="#{user.password}"/><br>
        <input type="submit" th:value="#{user.login}">
    </form>
</div>
<script th:inline="javascript">
    //选中语言
    $("#locale").find('option[value="' + LANG_COUNTRY + '"]').attr('selected', true);
    //切换语言
    $("#locale").change(function () {
        $.get(ROOT + '/?lang=' + $("#locale").val(), function () {
            location.reload();
        });
    });
</script>

</body>
</html>

运行

点击运行

浏览器访问 http://localhost:8080/
浏览器访问 http://localhost:8080/login

spring-boot-demo-170-01.png
spring-boot-demo-170-03.png
spring-boot-demo-170-05.png

参考

如果您喜欢本Spring Boot入门样例和样例代码,请点赞Star

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358

推荐阅读更多精彩内容