在一个Web应用中,通常会采用MVC设计模式来分别实现对应的模型、视图和控制器,其中,视图是用户看到并与之交互的界面。对最初的Web应用来说,视图是由HTML元素组成的静态界面,而后期的Web应用更倾向于使用动态模板技术,从而实现前后端分离和页面的动态数据展示。Spring Boot框架为简化项目的整体开发,对一些常用的视图技术也实现了整合支持,并主要推荐整合模板引擎技术来实现前端页面的动态化内容。本章将对Spring Boot支持的视图技术进行介绍,并使用Spring Boot整合其中常用的Thymeleaf模板引擎进行视图页面的实现。
表4-1 Thymeleaf常用标签
板进行纯HTML5的页面开发,可以使用data-th-属性替换th:属性进行页面开发。
首先必须保证引入Thymeleaf依赖。
org.springframework.boot
spring-boot-starter-thymeleaf
其次,在全局配文件中配置Thymeleaf模板的一些参数。如一般Web项目都会使用下列配置:
#模板缓存:开启,建议开发阶段为false,开发后改为true
spring.thymeleaf.cache = true
#模板编码:UTF-8
spring.thymeleaf.encoding = UTF-8
#模板样式:HTML5
spring.thymeleaf.mode = HTML5
#指定模板页面存放的路径:/templates/下
spring.thymeleaf.prefix = classpath:/templates/
#指定模板页面名称的后缀
spring.thymeleaf.suffix = .html
这里讲解Spring Boot与Thymeleaf模板引擎的整合使用。
步骤2:编写全局配置文件application.properties,内容如下:
#模板缓存:开启,建议开发阶段为false,开发后改为true
spring.thymeleaf.cache = true
#模板编码:UTF-8
spring.thymeleaf.encoding = UTF-8
#模板样式:HTML5
spring.thymeleaf.mode = HTML5
#指定模板页面存放的路径:/templates/下
spring.thymeleaf.prefix = classpath:/templates/
#指定模板页面名称的后缀
spring.thymeleaf.suffix = .html
步骤3:在com.itheima下创建包controll,包下创建一个用于前端模板页面动态数据替换效果测试的访问实体类LoginController.java,代码如下:
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Calendar;
//步骤1:添加controller注解,表明了这个类是一个控制器类
@Controller
public class LoginController {
//步骤2:添加@RequestMapping注解为下面的方法设置访问路径,为控制器指定可以处理的URL请求,这里为方法处的标记,但类定义处未标注,URL相对于web目录下的根目录
@RequestMapping("/toLoginPage")
//步骤3:完成方法编写
public String login(Model model){
//借助日历对象Calendar的.getInstance()获取当前的时间,然后调用get()方法获得当前的年份,如今天是2020,则i是2020
int i=Calendar.getInstance().get(Calendar.YEAR));
model.addAttribute("currentYear",i); //i存入model对象
return "login";//跳转到login.html,因为全局配置中已写明后缀,可不写后缀
}
}
步骤4:在templates中创建一个用户登录的模板页面login.html(前端页面的设计这里不作详细阐述,仅做引入方法介绍 )
首先引入静态资源,static中引入Login的静态资源(复制-粘贴),里面包含CSS文件和一张图片,(相关资源包可从百度云下载,下载地址:https://pan.baidu.com/s/1iJFPheqPdtG1e9FFoPeVgg)
login.html也建议引入,示例代码如下:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1,shrink-to-fit=no">
<title>用户登录界面title>
<link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
<link th:href="@{/login/css/signin.css}" rel="stylesheet">
head>
<body class="text-center">
<form class="form-signin">
<img class="mb-4" th:src="@{/login/img/login.jpg}" width="72" height="72">
<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">
<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>
<p class="mt-5 mb-3 text-muted">© <span th:text="${currentYear}">2018span>-<span th:text="${currentYear}+1">2019span>p>
<a class="btn btn-sm" th:href="@{/toLoginPage(l='zh_CN')}">中文a>
<a class="btn btn-sm" th:href="@{/toLoginPage(l='en_US')}">Englisha>
form>
body>
html>
步骤5:测试:启动项目启动类:Chapter04Application,成功运行访问http://localhost:8080/toLoginPage
说明,前面代码
spring.thymeleaf.prefix=classpath:/templates/
后面多了一个空格,如果是复制的同样多了空格,会出现如下显示页面:
可以注意到,文中出现2020-2021,正是我们用模型中的数据实现的替换部分。乱码问题我们在下一节解决。
步骤1:在resources下创建名称为i18n的文件夹,并在该文件夹中根据需要编写对应的多语言国际化文件login.properties、login_zh_CN.properties、login_en_US.properties.
其中,login.properties(默认语言配置文件)、login_zh_CN.properties(自定义中文国际化配置文件)代码相同如下:
login.tip=请登录
login.username=用户名
login.password=密码
login.rememberme=记住我
login.button=登录
login_en_US.properties为英文,代码如下:
login.tip=Please sign in
login.username=Username
login.password=Password
login.rememberme=Remember me
login.button=Login
步骤2:全局配置文件application.properties添加配置国际化文件
# 配置国际化文件基础名
spring.messages.basename=i18n.login
本行代码设置了自定义国际化文件的基础名,其中,i18n表示国际化文件相对项目类resources的位置,login表示多语言文件的前缀名为login_
步骤3:定制区域信息解析器
国际化语言的设置和展示,默认是使用请求头中的语言信息(浏览器语言信息)自动进行语言切换的,有些项目上还会提供手动语言切换的功能。这就需要定制区域解析器了。
在charter04项目中创建名为com.itheima.config的包,并在该包下创建一个用于定制国际化功能区域信息解析器的自定义配置类MyLocalResovel,内容如下:
package com.itheima.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
/**
* @Classname MyLocalResovel
* @Description 自定义区域信息解析器配置类
* @Date 2019-3-1 17:24
* @Created by CrazyStone
*/
@Configuration
public class MyLocalResovel implements LocaleResolver {
// 自定义区域解析方式,点击LocaleResolver部分,按ALT+ENTRE,可重写resolveLocale和setLocale方法
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
// 获取页面手动切换传递的语言参数l
String l = httpServletRequest.getParameter("l");
// 获取请求头自动传递的语言参数Accept-Language
String header = httpServletRequest.getHeader("Accept-Language");
Locale locale=null;
// 如果手动切换参数不为空,就根据手动参数进行语言切换,否则默认根据请求头信息切换
if(!StringUtils.isEmpty(l)){
String[] split = l.split("_");
locale=new Locale(split[0],split[1]);
}else {
// 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 httpServletRequest, @Nullable
HttpServletResponse httpServletResponse, @Nullable Locale locale) {
}
// 将自定义的MyLocalResovel类重新注册为一个类型LocaleResolver的Bean组件
@Bean
public LocaleResolver localeResolver(){
return new MyLocalResovel();
}
}
MyLocalResovel配置类实现了LocaleResovel接口,并重写了LocaleResovel接口的resloveLocale()方法解析自定义语言。使用@Bean注解将当前配置类注册成Sping容器中一个Bean组件。这样就可以覆盖默认的LocaleResolver组件。
步骤4:页面国际化使用
参阅前面已设置好的login.html,文中,使用Thymeleaf模块的#{}消息表达式设置了国际化展示的一部分信息。当对记住我remenberme进行国际化设置时,需要在标签外部设置国际化的remenberme,这里使用了行内表达式[[#{login.rememberme}]]动态获取国际化文件中的login.remenberme信息。
步骤5:整合效果测试
启动项目启动类:Chapter04Application,成功运行访问http://localhost:8080/toLoginPage
中文乱码没有解决,这是因为,IDEA开发工具编写的Properties配置文件默认使用的是GBK编码格式,修正方法:
在IDEA中,依次选择:File->Setting,搜索’File Encodings’进行设置,在Defalut encoding for properties files修改为UTF-8,同时勾选后面的Transparent native-to-ascii conversion选项。
需要说明的是,这种方法,仅对当前项目有效。后续项目的Properties配置文件仍为GBK编码格式,能过File-Other Settings-Settings for New Projects,同样搜索’File Encodings’进行,并参考下图进行设置,则可保证后续项目的Properties配置文件为UTF-8编码.
最后,重启项目启动类:Chapter04Application,成功运行访问http://localhost:8080/toLoginPage,效果如下图:
至此,Thymeleaf 数据页面展示和配置国际化页面实践完成。