目录:
作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!
该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!(侵权可联系我,进行删除,如果雷同,纯属巧合)
1. Thymeleaf “标准表达式” :
Thymeleaf 模板引擎 提供了 多种标准表达式语法,具体语法内容如下 :
表达式语法 说明 ${…} 变量表达式,表示从 后端 传递到 前端的 模型 ( 也称 "上下文" ) 获取的 “指定名称”的 变量 的 值。 *{…} 选择变量表达式 ,一般用于从 “被选定对象” 中 获取 “变量值” ( 而不是从 “上下文” 中获取 变量值 ) ,如果没有选定对象,则 和变量表达式一样。 #{…} 消息表达式,#{…}表达式 用于从 消息源(message sources)中 检索本地化的消息。
#{…}表达式 通常用于 替换静态文本 ,这些消息可以存储在 外部的属性文件 ( 如 .properties文件 )中,并由 Thymeleaf 在 渲染时 动态解析和 插入。
ps :
① 主要用于 “国际化内容” 的 “替换和展示”, 其 一般是结合 "国际化配置"的相关知识点 一起使用的。
② 通过 “消息表达式” 来从 消息源 ( 如: .properties文件 ) 中获得 “属性值”。@{…} 链接表达式,该表达式用于 构建 URL。使用该表达式 将会 生成一个 URL字符串,可以是一个绝对 URL,也可以是一个 相对于当前上下文的 URL。这个表达式通常在 HTML 的 href、src、action等属性中使用功能 ,通过该功能来 动态生成链接 或 资源的 URL。 ~{…} 片段表达式 ,用于 引用页面中的一个模板片段 ( 到别的页面中),该表达式 一般配合th:insert 或 th:replace 标签使用。 在上面表格中列举了 Thymeleaf 模板引擎最常用的简单表达式语法,并对这些语法进行了功能说明。除此之外,Thymeleaf 还提供了 其他更多的语法支持,例如 文本表达式、 算术表达式、布尔表达式 、比较表达式 等。
${ } : 变量表达式 ( 从 “上下文” 中获取 “变量值”)
${…} : 表达式 ,表示从 后端 传递到 前端的 模型 ( 称为 "上下文" ) 中获取的 “指定名称”的 变量 的 值。( 从"上下文" 中 获取 “变量值” ), 例子代码如 :
<!DOCTYPE html> <!-- 配置开启“Thymeleaf模板引擎页面开发 ”--> <!-- xmlns:th="http://www/thymeleaf.org" 表示引入“Thymeleaf模板引擎” --> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Thymeleaf中的的 ${…} 变量表达式</title> </head> <body> <!-- ${title} : Thymeleaf变量表达式,表示从后端传递到前端的模型 (也称:上下文)中获取"指定名称"的变量的值 th:text : Thymeleaf标签,表示"动态显示/动态修改"该标签中的值 ( 会进行HTML”转义“,确保为“纯文本内容”) th:text="${title}" : 如果"上下文"中有title变量的值,则动态修改标签中的值;没有没有该变量值,则p标签显示的值还是“默认文本内容” --> <p th:text="${title}"> 默认标题 </p> </body> </html>
上述代码示例使用了Thymeleaf模板的 变量表达式 : ${…} 用来 动态设置 / 动态修改 p标签 的 值,如果 ① 当前程序未启动 或 ② 上下文中不存在 title变量,则 p标签 显示的值为 “默认标题” ( 显示默认文本值 )。
如果当前上下文中 存在title变量并且程序已经启动,当前p标签中的 默认文本内容 将会被 title 变量 的 值所 “替换”,从而达到在 Thymeleaf模板引擎页面 中 “动态修改/替换” 文本的效果。
*{ } : 选择变量表达式 ( 从 “被选定对象” 中获取 “变量值”)
选择变量表达式和 变量表达式 “用法类似”,一般用于从"被选定对象" 中 获取 "属性值"/ “变量值” ( 而不是从 “上下文” 中获取属性值 ) ,如果没有选定对象,则 和变量表达式一样,示例代码如下 :
two.html :
<!DOCTYPE html> <!-- 配置开启“Thymeleaf模板引擎页面开发 ”--> <!-- xmlns:th="http://www/thymeleaf.org" 表示引入“Thymeleaf模板引擎” --> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Thymeleaf中的的 *{…} 选择变量表达式</title> </head> <body> <!-- th:object : 模板片段设置一个"中心对象",使得你可以在模板中方便地 "访问"该对象的属性,而"无需每次"都写出完整的表达式。 th:text : 动态修改标签文本内容 ${} : 变量表达式,表示从"上下文"中获取"变量值" *{} : 选择变量表达式,从"被选定的对象"中获得"变量值"/"属性值" ${#object.firstName} : 使用Thymeleaf的内置对象object获取当前上下文对象中的firstName属性值 user为存储在session中的对象 --> <div th:object="${session.user}"> <p>Name: <span th:text="${#object.firstName}">姓</span></p> <p>Surname: <span th:text="*{lastName}">名</span></p> <p>Nationnality: <span th:text="*{nationality}">国籍</span></p> </div> </body> </html>
ThymeleafController.java :
@Controller public class ThymeleafController { @GetMapping("/toTwo") public String toTwo(HttpSession session) { //存储一个对象在Session中,前端获得该对象的数据信息 User user = new User(); user.setFirstName("张"); user.setLastName("三"); user.setNationality("中国"); session.setAttribute("user",user); return "two"; //返回值为: String类型,返回一个视图页面给前端 } }
<!-- @{ } : 链接表达式,该表达式最后会生成一个URL字符串 th:href : 为href属性赋值 --> <a href="details.html" th:href="@{/order/details(orderId=${orderId})}">view</a>
上述代码中,链接表达式@{ } 分别编写了 绝对链接地址 和 相对链接地址。在 有参表达式 中,需要按照 :
@{ 路径 (参数名称=参数值 , 参数名称=参数值 …) } 的 形式编写 ,同时该 参数的值可以使用变量表达式来传递动态参数值。
#{ } : 消息表达式 ( 主要用于 “国际化内容” 的 “替换和展示” )
消息表达式 : 主要用于 Thymeleaf 模板页面 国际化内容的动态"替换" 和 “展示”。使用消息表达式 #{…} 进行 国际化设置时, 还需要提供一些国际化配置文件。
通过 “消息表达式” 来从 消息源 ( 如: .properties文件 ) 中获得 “属性值” ,其 一般是结合 "国际化配置"的相关知识点 一起使用的。例子可参考下面的具体案例。
@{ } : 链接表达式 ( 使用该表达式会生成一个 “URL字符串” )
链接表达式,用于 构建 URL。一般用于 "页面跳转"或者 "资源的引入" , 使用该表达式 将会 生成一个 URL字符串,可以是一个绝对 URL,也可以是一个 相对于当前上下文的 URL。这个表达式通常在 HTML 的 href、src、action等属性中使用功能 ,通过该功能来 动态生成链接或 资源的 URL。同时链接表达式在Web开发中占据着非常重要的地位 。示范代码如下 :
four.html :
<!DOCTYPE html> <!-- 配置开启“Thymeleaf模板引擎页面开发 ”--> <!-- xmlns:th="http://www/thymeleaf.org" 表示引入“Thymeleaf模板引擎” --> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Thymeleaf中的的 @{…} 链接表达式</title> </head> <body> <!-- @{} : 链接表达式,使用该表达式会生成一个URL字符串 ${} : 变量表达式,从上下文中获得"变量值" th:href : 动态设置href属性的值 --> <a th:href="@{ ${url} }">view</a> </body> </html>
ThymeleafController.java :
@Controller public class ThymeleafController { @GetMapping("/toFour") public String toFour(Model model) { //存储一个对象在Session中,前端获得该对象的数据信息 model.addAttribute("url", "/toDetails"); return "biaodashi/four"; //返回值为: String类型,返回一个视图页面给前端 } @GetMapping("/toDetails") public String toDetails() { return "biaodashi/Details"; //返回值为: String类型,返回一个视图页面给前端 } }
Details.html :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Details.html</title> </head> <body> 123 </body> </html>
~{ } : 片段表达式 ( 引入页面中的 “模板片段” )
片段表达式 ,用于 引用页面中的一个模板片段 ( 到别的页面中),该表达式 一般配合 th:fragment标签 、th:insert标签 或 th:replace 标签使用。
代码例子如下 :footer.html :
<!DOCTYPE html> <!--配置开启Thymeleaf模板引擎页面开发--> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>footer.html</title> </head> <body> <footer th:fragment="footer"> <p>这是一个公共的footer部分。</p> </footer> </body> </html>
index.html :
<!DOCTYPE html> <!--配置开启Thymeleaf模板引擎页面开发--> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>主页面</title> <h1>欢迎来到主页面</h1> </head> <body> <!-- 使用 ~{} :片段表达式引入 "footer模板 " --> <!-- ~{footer :: footer} : 获得footer.html中的 footer片段 --> <div th:insert="~{footer :: footer}"></div> <p>这是主页面的内容。</p> </body> </html>
上述代码中,使用 th:insert 属性将 footer片段模板引用到该<div>标签中。第一个footer为 模板名称 ( 视图页面的名称 ),第二个footer为模版片段的名称。
2. Thymeleaf “内置对象”
Thymeleaf 为 变量所在域 提供了一些 内置对象 。
Thymeleaf 的“内置对象”指的是在 Thymeleaf 模板引擎中 预定义的 一组对象 ( 不用什么配置,就已经存在的、可直接使用的对象 ),这些 对象可以 直接在模板中使用,而 无需通过后端代码显式地 传递给模板。
Thymeleaf内置对象提供了对常用功能的访问,如 ① 访问上下文数据、② 执行常见的字符串 、③ 数值操作、④ 格式化日期和时间、⑤ 国际化等。
Thymeleaf内置对象的作用主要是简化模板的 开发过程,可以在模板中直接使用这些内置的功能,而 不需要编写额外的后端代码。通过内置对象,开发者可以更高效地在模板中处理数据、控制流程、显示消息等。
常见的 Thymeleaf “内置对象” 有 :
Thymeleaf 内置对象 描述 #ctx 或 #context 上下文“对象” #vars 上下文“变量” #locale 上下文区域设置 / 本地化“对象” #dates 日期工具 对象 #calendars 日历工具 对象 #numbers 数字工具 对象 #strings 字符串工具 对象 #arrays 数组工具 #lists 列表工具
Thymeleaf 内置对象 描述 #sets 集合工具 #maps 映射工具 #request 或 #httpServletRequest ( 仅限Web Context ) HTTP “请求” 对象 #response 或 #httpServletResponse ( 仅限Web Context ) HTTP “响应” 对象 #session ( 仅限Web Context ) HttpSession对象 #ServletContext ( 仅限Web Context ) ServletContext对象 结合上述内置对象的说明,假设要在 Thymeleaf模板引擎页面中 动态获取 “当前国家信息” ,可以使用#locale 内置对象,示例代码如下 :
<!DOCTYPE html> <!-- 配置开启“Thymeleaf模板引擎页面开发 ”--> <!-- xmlns:th="http://www/thymeleaf.org" 表示引入“Thymeleaf模板引擎” --> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <title>#locale内置对象的使用</title> </head> <body> The locale country is : <span th:text="${#locale.country}">US</span> </body> </html>
上述代码中,使用 ${#locale.country} :动态获取当前用户所在国家信息,其中 <span>标签内默认内容为 : US(美国),程序启动后通过浏览器查看当前页面时,Thymeleaf会通过浏览器语言设置来 识别当前用户所在国家信息,从而实现动态替换。
3. Thymeleaf “基本使用”
Thymeleaf 模板 的 “基本配置”
在 Spring Boot 项目中使用 Thyneleaf模板,首先必须保证 引入Thymeleaf依赖,示例代码如下:
<!-- thymeleaf模板引擎 的 依赖启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
其次,在 全局配置文件中 配置 Thymeleaf 模板的一些参数。一般 Web 项目都会使用下列配置 :
#开启Thymeleaf模版缓存,默认为true (启用模版缓存),开发中通常会关闭,保证"项目调试过程中"数据能够及时响应,上线稳定后应保持为true spring.thymeleaf.cache = true #设置模版编码 spring.thymeleaf.encoding=UTF-8 #应用于模版的模版模式 spring.thymeleaf.mode=HTML5 #指定模版页面存储路径 ( 默认为:classpath:/templates/ ) spring.thymeleaf.prefix=classpath:/resources/templates/ #指定模版页面名称的后缀 ( 默认为: .html ) spring.thymeleaf.suffix=.html
静态资源 的 “访问”
开发 Web 应用时,难免需要 使用静态资源。Spring Boot默认设置 了 静态资源的 访问路径默认将/**所有访问 映射到以下目录:
(1) classpath:/META-INF/resources/ :
项目类路径 下的 META-INF 文件夹 下的 resources 文件夹下 的 所有文件。
(2) classpath:/resources/ :
项目类路径 的 resources 文件夹下 的 所有文件。
(3) classpath:/static/ : 项目类路径下 的 static 文件夹 下的 所有文件。
(4) classpath:/public/ : 项目类路径下 的 public 文件夹下 的 所有文件。
使用 Spring Initializr 方式创建的 SprinBoot 项目会默认生成一个 resources 目录,在resources 目录中 新建 public、resources、static 3个子目录 ,Spring Boot默认会依次从 public、resources、static 里面 查找静态资源。
4. Spring Boot 与 Thymeleaf模板引擎 的 “整合使用”
① 创建项目
关于 静态资源的项目结构 :
② 编写配置文件
#开启Thymeleaf模版缓存,默认为true (启用模版缓存),开发中通常会关闭,保证"项目调试过程中"数据能够及时响应,上线稳定后应保持为true spring.thymeleaf.cache=false
③ 创建 Web 控制类
在 项目中创建controller 层包,并在该包下创建一个用于前端模板页面 动态数据替换效果测试的 访问实体类 : LoginController,代码文件如下所示 :
LoginController.java :
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import java.util.Calendar; @Controller //加入到IOC容器中 public class LoginController { /** * 获取并封装当前年份,跳转到登录页 login.html */ @GetMapping("/toLoginPage") public String toLoginPage(Model model) { //通过Model来向前端传递数据 model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR)); return "login"; //返回值为String类型,可用于返回一个"视图页面" } }
④ 创建 “模板页面” 并引入 “静态资源文件”
在 resources 的 templates 目录 下创建一个 用户登录的 模板页面 : login.html,代码如下所示 :
login.html :
<!DOCTYPE html> <!-- 配置开启Thymeleaf模板引擎页面开发 --> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <!-- th:href : 设置href属性的值 @{} : 链接表达式,该表达式得到一个URL字符串,赋值给href属性 --> <link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet"> <link th:href="@{/login/css/signin.css}" rel="stylesheet"> <title>用户登录页面</title> </head> <body class="text-center"> <!-- 用户登录form表单--> <form class="form-signin"> <!-- th:src : 设置src属性的值 @{} : 链接表达式,该表达式得到一个URL字符串,赋值给src属性 --> <img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal" >请登录</h1> <input type="text" class="form-control" placeholder="用户名" required="" autofocus=""> <input type="password" class="form-control" placeholder="密码" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"/>记住我</label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" >登录</button> <!-- th:text : 动态修改标签中的值 ${} : 从"上下文"中获得指定变量的值 th:text="${currentYear}" : 用后端传来的currentYear变量的值来动态替换2018 --> <p class="mt-5 mb-3 text-muted">@<span th:text="${currentYear}">2018</span>-<span th:text="${currentYear}+1">2019</span></p> </form> </body> </html>
⑤ 效果测试
项目启动成功后,浏览器上访问 : http://localhost:8080/toLoginPage 进入登录页面,效果如下图所示 :
5. 使用 Thymeleaf “配置国际化页面” ( Spring Boot 国际化功能实现 )
① 创建项目
关于 静态资源的项目结构 :
② 创建 Web 控制类
在 项目中创建controller 层包,并在该包下创建一个用于前端模板页面 动态数据替换效果测试的 访问实体类 : LoginController,代码文件如下所示 :
LoginController.java :
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import java.util.Calendar; @Controller //加入到IOC容器中 public class LoginController { /** * 获取并封装当前年份,跳转到登录页 login.html */ @GetMapping("/toLoginPage") public String toLoginPage(Model model) { //通过Model来向前端传递数据 model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR)); return "login"; //返回值为String类型,可用于返回一个"视图页面" } }
③ 编写 “多语言国际化文件”
在项目的类路径 resources 下创建名称为 i18n 的 文件夹,并在该文件夹中根据需要编写对应的多语言国际化文件 : login.properties、login_zh_CN.properties 和 login_en_US.properties 文件,代码文件如下所示 :
( 注意点 :
其他语言国际化文件 的 名称必须严格按照 : “ 文件前缀名_语言代码_国家代码.properties” 的 形式命名“。)login.properties :
login.tip=请登录 login.username=用户名 login.password=密码 login.rememberme=记住我 login.button=登录
login_zh_CN.properties : ( 文件前缀名_语言代码_国家代码.properties )
login.tip=请登录 login.username=用户名 login.password=密码 login.rememberme=记住我 login.button=登录
login_en_US.properties :( 文件前缀名_语言代码_国家代码.properties )
login.tip=please sign in login.username=Username login.password=Password login.rememberme=Remember me login.button=Login
login.properties 为自定义默认语言配置文件,login_zh_CN.properties为自定义中文国际化文件 和 login_en_US.properties 为自定义英文国际化文件。
需要说明的是,Spring Boot 默认识别 的 语言配置文件 为 : 类路径 resources 下 的 messages.properties , 其他语言国际化文件的 名称必须严格按照 : “ 文件前缀名_语言代码_国家代码.properties” 的 形式命名“。
—( 默认的语言配置文件为 :messages.properties , 此时全局配置文件 中的 "国际化文件基础名" 为 : messages , 当然此时这个配置信息可忽略不配置也可以的 )注意点 :
可通过 全局配置文件 来 修改 默认的语言配置文件 ( 指定自定义的语言配置文件 为 “默认使用 的 语言配置文件”)。
④ 编写 “全局配置文件” ( 指定 自定义的 “语言配置文件” 来 替代 “默认的语言配置文件” )
# 开启Thymeleaf模版缓存,默认为true (启用模版缓存),开发中通常会关闭,保证"项目调试过程中"数据能够及时响应,上线稳定后应保持为true spring.thymeleaf.cache=false # 配置国际化文件基础名 / 修改"默认的语言配置文件" # 默认的语言配置文件为 : 类路径resources下的 messages.properties文件,现在将其修改为为 类路径resources下 i18n文件夹下的 login.properties ,所以有此时的 "国际化文件基础名"为 login spring.messages.basename=i18n.login
需要说明的是,Spring Boot 默认识别 的 语言配置文件 为 : 类路径 resources 下 的 messages.properties , 其他语言国际化文件 的 名称必须严格按照 : “ 文件前缀名_语言代码_国家代码.properties” 的 形式命名“。
-------( 默认的语言配置文件为 :messages.properties , 此时的国际文件基础名为 : messages ,是 可以不用在”全局配置文件“中 配置的 。如果默认的 语言配置文件修改为 :login.properties , 那么此时的 "国际文件基础名" 为 : login , 其的其他语言国家化文件 要 “上面要求” 创建,如 : login_ zh_CN.properties )
上面的 全局配置文件 中,通过 spring.messages.basename = i18n.login ,指定 国际化文件基础名 为 i18文件夹下的 login ( 此时对应的默认的 "语言配置文件" 为 : login.properties ) , 此时 login表示 多语言文件 的"前缀名"。
如果 开发者完全按照 Spring Boot 默认识别机制,在项目类路径resources 下 编写 messages.properties等国际化文件,可以省略国际化文件基础名的配置 。
—( 如果按默认识别机制在 resources 目录 下 编写 messages.properties等国际化文件 ,就可以 省略 “全局配置文件” 中的配置 )。
⑤ 定制 “区域信息解析器”
在完成上一步中 多语言国际化文件的 编写和配置后,就可以正式在前端页面中 结合Thymeleaf模板相关属性 进行国际化语言设置 和 展示 了。
不过这种实现方式默认是 使用请求头中的语言信息 ( 浏览器语言信息 ) 自动 进行 语言切换的,有些项目还会提供手动语言切换的功能,这就需要 定制 “区域解析器” 了。
在项目中创建名 config的包,并在该包下创建个 用于定制 "国际化功能区域信息解析器"的自定义配置类 : MyLocalResovel,代码文件如下所示 :
MyLocaleResolver.java :
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.apache.catalina.util.StringUtil; import org.springframework.cglib.core.Local; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.thymeleaf.util.StringUtils; import java.util.Locale; @Configuration //标记为配置类 public class MyLocaleResolver implements LocaleResolver { //该配置类用于定制 "国际化功能区域信息解析器" /** * 自定义区域解析方式 : * ① 通过"手动切换"的形式来进行"语言环境"的修改 * ② 如果没有"手动切换",则按照请求头中的 "Accept-Language的语言参数" 信息来进行"语言环境"的修改 * ---不管哪种方式,最后都是将 相关的"语言信息" "作为参数" 来创建 Locale对象,并将该对象作为"返回值" */ @Override public Locale resolveLocale(HttpServletRequest request) { //获取 "页面手动切换" "传递的参数:language" ---手动切换 //language参数的形式为: zh_CN 或 en_US String language = request.getParameter("language"); //获取"请求头"自动传递的语言参数Accept-Language ---根据浏览器信息"自动切换" //Accept-Language的语言参数形式为: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7 String header = request.getHeader("Accept-Language"); Locale locale = null; //如果"手动切换参数"不为空,则根据手动参数进行切换,否则默认根据"请求头"信息切换 if (!StringUtils.isEmpty(language)) { //手动参数不为空,则用"手动参数"来进行"语言设置" // .split() : 根据给定"字符"/“正则表达式”的匹配 "拆分此字符串" String[] split = language.split("_"); //以 _ 来进行拆分,因为language参数的形式为: zh_CN 或 en_US locale = new Locale(split[0], split[1]); } else { //用浏览器中的请求头信息中的language参数来进行"语言设置" //Accept-Language的语言参数形式为: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7 String[] splits = header.split(","); String[] split = splits[0].split("-"); locale = new Locale(split[0], split[1]); } return locale; } @Override public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { } /** * 将自定义的MyLocaleResolver类 "重新注册"为一个类型为 : LocaleResolver 的 Bean组件 */ @Bean //将方法的返回值对象加入到IOC容器中 public LocaleResolver localeResolver() { return new MyLocaleResolver(); } }
上面的文件代码中, MyLocalResovel配置类实现了 LocaleResovel接口 , 并重写了 LocaleResove接口的 resolveLocale( )方法来 解析自定义语言。使用 @Bean 注解 将 当前配置类 注册成 Spring 容器中一个 Bean 组件。这样就可以覆盖默认的 LocaleResolver 组件。在重写的resoiveLocale( )方法中,可以根据不同的需求切换语言信息从而获取请求的参数,只有请求参数不为空时,才可以进行语言的切换。
需要注意的是,在请求参数 : language的 语言手动切换组装时,使用的是下划线这是由多语言配置文件的 格式决定的 ( 例如 language = ‘zh_CN’ ) ; 而在请求头参数Accept-Language 的 语言自动切换组装时,使用的是短横线“_”进行的切割,这是由浏览器发送的 请求头信息 样式决定的 ( 例如 Accept-Language : en-US,en;q=0.9,zh-CN;q=0.8,zh;9=0.7 )。
⑥ 定制 “国际化” “视图页面”
打开项目 templates 模板文件夹中的用户登录页面 login.html,结合 Thymeleaf 模板引擎实现国际化功能,代码文件如下所示 :
login.html :
<!DOCTYPE html> <!-- 配置开启Thymeleaf模板引擎页面开发 --> <html lang="en" xmlns:th="http://www/thymeleaf.org"> <head> <meta charset="UTF-8"> <!-- th:href : 设置href属性的值 @{} : 链接表达式,该表达式得到一个URL字符串,赋值给href属性 --> <link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet"> <link th:href="@{/login/css/signin.css}" rel="stylesheet"> <title>用户登录页面</title> </head> <body class="text-center"> <!-- 用户登录form表单--> <form class="form-signin"> <!-- th:src : 设置src属性的值 @{} : 链接表达式,该表达式得到一个URL字符串,赋值给src属性 --> <img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72"> <!-- #{} : 消息表达式 ,通过该表达式来从"消息源" (如: .properties文件)中获取"属性值",其一般结合"国际化"的相关知识点一起使用 --> <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">请登录</h1> <input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""> <input type="password" class="form-control" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <!-- [[#{login.rememberme}]] : 使用行内表达式来动态获取国际化文件中的 login.rememberme信息 --> <label> <input type="checkbox" value="remember-me"/>[[#{login.rememberme}]]</label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.button}">登录</button> <!-- th:text : 动态修改标签中的值 ${} : 从"上下文"中获得指定变量的值 th:text="${currentYear}" : 用后端传来的currentYear变量的值来动态替换2018 --> <p class="mt-5 mb-3 text-muted">@<span th:text="${currentYear}">2018</span>-<span th:text="${currentYear}+1">2019</span></p> <a class="btn btn-sm" th:href="@{/toLoginPage(language='zh_CN')}">中文</a> <a class="btn btn-sm" th:href="@{/toLoginPage(language='en_US')}">English</a> </form> </body> </html>
⑦ 整合效果测试
项目启动成功后,浏览器上访问 : http://localhost:8080/toLoginPage 进入登录页面,效果如下图所示 :
( 如有乱码问题,可对 IDEA开发工具中的 Properties文件编码格式进行设置 / 或其他原因导致的乱码,可自行解决 )