目录
静态目录的优先级和存放资源类型探究
查询类的快捷键:ctrl+shift+r
搜ResourceProperties
private static final String[] CLASSPATH_RESOURCE_LOCATIONS =
new String[]{
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
};
优先级
resources>static>public
资源存放
resource: 存放上传的资源
static: 存放css、图片
public: 存放公共资源例如js
简单应用
thymeleaf官网地址: https://www.thymeleaf.org/
官网上一个简单的html
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Good Thymes Virtual Grocery</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" media="all"
href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
</head>
<body>
<p th:text="#{home.welcome}">Welcome to our grocery store!</p>
</body>
</html>
引入命名空间
xmlns: xml namespace的简写
引入命名空间可能会报一个错误,可以删除xmlns="http://www.w3.org/1999/xhtml"这个,使用 xmlns:th="http://www.thymeleaf.org"就可以了
xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
thymeleaf的一些语法
- 简单表达式:
变量表达式: ${…}
选择变量表达式: *{…}
消息表达: #{…}
链接URL表达式: @{…} - 文字
文本文字:‘one text’,‘Another one!’,…
号码文字:0,34,3.0,12.3,…
布尔文字:true,false
空文字: null
文字标记:one,sometext,main,… - 文字操作:
字符串串联: +
文字替换: |The name is ${name}| - 算术运算:
二元运算符:+,-,*,/,%
减号(一元运算符): - - 布尔运算:
二元运算符:and,or
布尔否定(一元运算符): !,not - 比较和平等:
比较:>,<,>=,<=(gt,lt,ge,le)
等号运算符:==,!=(eq,ne) - 条件运算符:
如果-则: (if) ? (then)
如果-则-否则: (if) ? (then) : (else)
默认: (value) ?: (defaultvalue)
引入css地址
上述提到链接URL表达式: @{…}
<!-- Bootstrap core CSS -->
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<!-- Custom styles for this template -->
<link th:href="@{/css/signin.css}" rel="stylesheet"/>
sprigmvc+thymeleaf
官网中的doc中有这一点
这个里面讲的是Spring MVC和Thymeleaf:如何从模板访问数据:
在典型的Spring MVC应用程序中,@Controller类负责使用数据准备模型图并选择要渲染的视图。此模型图允许对视图技术进行完全抽象,并且在Thymeleaf的情况下,将其转换为Thymeleaf上下文对象(Thymeleaf 模板执行上下文的一部分),该对象使所有定义的变量可用于模板中执行的表达式。
sprigmvc+thymeleaf
- Spring model attributes(spring模型属性)
- Request parameters(请求参数)
- Session attributes(会话属性)
- ServletContext attributes(ServletContext属性)
- Spring beans(@Bean)
这里就讲一下模型属性
详情参考文档: https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html
国际化
在resources 目录下创建i18n文件夹(i18n国际化缩写)
这里以登陆页面为例
- 创建login.properties文件
- 创建login_zh_CN.properties文件
- 自动生成Resource Bundle 'login’文件夹
- 点击Resource Bundle视图
- 点击+创建login.xxx
- 分别在默认、中文、英文输入内容
- 在页面中绑定国际化的内容
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
中英文互转
index.html页面中英文转换a标签
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
中英文互转配置
搜WebMvcAutoConfiguration
参考MessageCodesResolver方法重写
public MessageCodesResolver getMessageCodesResolver() {
if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
resolver.setMessageCodeFormatter(this.mvcProperties.getMessageCodesResolverFormat());
return resolver;
} else {
return null;
}
}
将请求传过来的关于语言的请求参数进行处理
package com.common.config;
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class MyLocalResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
//获取请求中的语言参数
String language = httpServletRequest.getParameter("l");
Locale locale = Locale.getDefault(); //如果没有使用默认的
//如果请求的语言参数不为空
if(!StringUtils.isEmpty(language)) {
//zh_CN
String[] split = language.split("_");
//国家,地区
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
在自定义的MyWebmvcConfig注册LocaleResolver
package com.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
//@EnableWebMvc
public class MyWebmvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
//自定义的国际化组件
@Bean
public LocaleResolver localeResolver() {
return new MyLocalResolver();
}
}
index.html代码
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<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"/>
<meta name="description" content=""/>
<meta name="author" content=""/>
<title>Signin Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<!-- Custom styles for this template -->
<link th:href="@{/css/signin.css}" rel="stylesheet"/>
</head>
<body class="text-center">
<form class="form-signin" action="dashboard.html">
<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>
<label class="sr-only" th:text="#{login.username}">Username</label>
<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.remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">[[#{login.btn}]]</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
</form>
</body>
</html>
DOM选择器语法(提出公共的代码)
根据vue将公共页面提出来的思路thymeleaf也能做到
commons.html
th:fragment=“topbar” //提取头部导航栏
th:fragment=“sidebar” //提取侧边栏
th:class="${active==‘list.html’?‘nav-link active’:‘nav-link’}" th:href="@{/emps}" //控制高亮
dashboard.html:
th:replace="~{commons/commons::topbar}" //从commons.html引入头部导航栏
th:replace="~{commons/commons::sidebar(active=‘main.html’)}" //引入侧边栏并传值给commons.html控制高亮
common.html
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<!-- 头部导航栏-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav>
<!--侧边栏-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a th:class="${active=='main.html'?'nav-link active':'nav-link'}" th:href="@{/index.html}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
<polyline points="9 22 9 12 15 12 15 22"></polyline>
</svg>
Dashboard <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart">
<circle cx="9" cy="21" r="1"></circle>
<circle cx="20" cy="21" r="1"></circle>
<path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
</svg>
Products
</a>
</li>
<li class="nav-item">
<a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}">
员工管理
</a>
</li>
</ul>
</nav>
</html>
dashboard.html引入
//部分代码
<!-- 顶部导航栏-->
<div th:replace="~{commons/commons::topbar}"></div>
<!-- 侧边栏-->
<div th:replace="~{commons/commons::sidebar(active='main.html')}"></div>
list.hmtl引入
//部分代码
<!--头部导航栏-->
<div th:replace="~{commons/commons::topbar}"></div>
<div th:replace="~{commons/commons::sidebar(active='list.html')}"></div>