模板引擎 thymeleaf、ContentNegotiatingViewResolver视图解析器(内容协商视图解析器)、格式化转换器

模板引擎 thymeleaf

SpringBoot给我们推荐的Thymeleaf,模板引擎有非常多,但再多的模板引擎,他们的思想都是一样的,什么样一个思想呢我们来看一下这张图。

模板引擎的使用:是为了实现数据分离(动态数据与静态数据)和代码重用

1、Thymeleaf 官网

2、Github 

3、Spring官方文档

thymeleaf 的依赖:

<!--thymeleaf模板-->
<dependency>
  <groupId>org.thymeleaf</groupId>
  <artifactId>thymeleaf-spring5</artifactId>
</dependency> <dependency>
  <groupId>org.thymeleaf.extras</groupId>
  <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

我们要使用thymeleaf,需要在html文件中导入命名空间的约束,

<html xmlns:th="http://www.thymeleaf.org">

Thymeleaf 的配置类

@ConfigurationProperties(
prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
private boolean checkTemplate = true;
private boolean checkTemplateLocation = true;
private String prefix = "classpath:/templates/";
private String suffix = ".html";
private String mode = "HTML";
private Charset encoding;
}

我们可以在其中看到默认的前缀和后缀!我们只需要把我们的html页面放在类路径下的templates下,thymeleaf就可以帮我们自动渲染了。

thymeleaf语法

我们可以使用任意的 th:* 来替换Html中原生属性的值

// 常用的标签	#4
Variable Expressions: ${...}:获取变量值、获取对象的属性、调用方法;
Message Expressions: #{...}:获取国际化内容;
Link URL Expressions: @{...}:定义URL;
<link th:href="@{/css/dashboard.css}" rel="stylesheet">
<script th:src="@{/js/jquery-3.2.1.slim.min.js}"></script> Fragment Expressions: ~{...}:片段引用表达式
<div th:insert="~{commons :: main}">...</div> // 常用的运算符
Boolean operations:(布尔运算)
Binary operators: and , or
Boolean negation (一元运算符): ! , not Comparisons and equality:(比较运算)
Comparators: > , < , >= , <= ( gt , lt , ge , le )
Equality operators: == , != ( eq , ne ) Arithmetic operations:(数学运算)
Binary operators: + , - , * , / , %
Minus sign (unary operator): - Text operations:(文本操作)
String concatenation: +
Literal substitutions: |The name is ${name}| Conditional operators:条件运算(三元运算符)
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue) // ====================================== Literals(字面量)
Text literals: 'one text' , 'Another one!' ,…
Number literals: 0 , 34 , 3.0 , 12.3 ,…
Boolean literals: true , false
Null literal: null
Literal tokens: one , sometext , main ,… Special tokens:
No-Operation: _ // ======================================
Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是一样;
补充:配合 th:object="${session.user}: <div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div> // =======================================
// 内置的工具对象 #19 #execInfo :有关正在处理的模板的信息。
#messages :在变量表达式中获取外部化消息的方法,与使用{{…}语法获取外部化消息的方法相同。
#uri:转义部分url/uri的方法
#conversions :执行配置的转换服务(如果有的话)的方法。
#dates :java.util.Date对象的方法:格式化、组件提取等。
#calendars :类似于日期,但适用于java.util.Calendar对象。
#numbers :格式化数字对象的方法。
#strings :字符串对象的方法:contains、startsWith、prepending/appending等。
#objects :通常用于对象的方法。
#bools:布尔求值的方法。
#arrays :数组的方法。
#lists:列表的方法。
#sets :集合的方法。
#maps :Map的方法。
#aggregates :在数组或集合上创建聚合的方法。
#ids:处理可能重复的id属性的方法(例如,作为迭代的结果)。 // 内置的基本对象: #18
#ctx : the context object.
#vars: the context variables.
#locale : the context locale.
#request : (only in Web Contexts) the HttpServletRequest object.
#response : (only in Web Contexts) the HttpServletResponse object.
#session : (only in Web Contexts) the HttpSession object.
#servletContext : (only in Web Contexts) the ServletContext object.

很多样式,我们即使现在学习了,也会忘记,所以我们在学习过程中,需要使用什么,根据官方文档来查询,才是最重要的,要熟练使用官方文档!

简单使用:

th:each

  • controller
@GetMapping("/emps")
public String list(Model model) { Collection<Employee> emps = employeeDao.getAllEmployee();
model.addAttribute("emps", emps); return "emp/list";
}

  • list.html

th:fragment

  • bar.html
<!--导航栏-->
<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/#" th:text="${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" th:href="@{/user/logout}">注销</a>
</li>
</ul>
</nav>

<div th:replace="~{commons/bar::topbar}"></div>

ContentNegotiatingViewResolver

目的:看看该 ContentNegotiatingViewResolver 视图解析器作用

首先在 WebMvcAutoConfiguration 找到注册的 Bean

@Bean
@ConditionalOnBean(ViewResolver.class)
@ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(beanFactory.getBean(ContentNegotiationManager.class));
// ContentNegotiatingViewResolver使用所有其他视图解析器来定位
// 设置该视图为较高的优先级
resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
return resolver;
}

点进 ContentNegotiatingViewResolver

找到对应的解析视图的代码:resolveViewName()

注解说明:@Nullable 即参数可为null

点进去

由此可得结论:ContentNegotiatingViewResolver 这个视图解析器就是用来组合所有的视图解析器的

继续往下看 getCandidateViews()方法

getBestView()方法

最终上述我们获得的视图都会返回到 调用者处。即 DiapatcherServlet 的 resolverViewName()方法

简要的调用关系如下:

因此,如果我要自定义视图解析器,需要首先实现 ViewResolver 接口,然后再将实现了该接口的类交给 Spring 的 Ioc 容器托管,使之成为一个 Bean。

public class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return null;
}
}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
// 在容器中注册 bean
@Bean
public ViewResolver myViewResolver() {
return new MyViewResolver();
} }

如何检验我们写的视图解析器起效了?

在DispathcerServlet类的 doDispatch()方法内 Debug一下即可:

ContentNegotiatingViewResolverViewResolver 的实现类,该解析基于 请求文件名(也就是:文件扩展名) 或请求头  Accept 解析视图。

ContentNegotiatingViewResolver 不会自行解析视图,而是委托给其他 ViewResolvers。

默认情况下,这些其他视图解析器会从应用程序上下文中自动获取。

此视图解析器通过配置的 ContentNegotiationManager 确定请求的媒体类型(也就是Mime 类型)。

确定请求的媒体类型后,此解析器向每个委托视图解析器查询 View,并确定请求的媒体类型是否与视图的 MediaType 兼容。返回最兼容的视图。

请注意,这些默认视图是作为候选者提供的,但仍需要具有请求的内容类型(通过文件扩展名,参数,Accept 请求头)。

例如,如果请求路径为:localhost:8080/view.html,则此视图解析器将查找具有  text / html内容类型。如果请求头是:Accept: text/html ;也具有相同的结果。

格式化转换器

WebMvcAutoConfiguration中:

@Bean
@Override
public FormattingConversionService mvcConversionService() {
WebConversionService conversionService = new WebConversionService(this.mvcProperties.getDateFormat());
addFormatters(conversionService);
return conversionService;
}

点击:getDateFormat()

发现SpringBoot默认的日期格式为:dd/MM/yyyy

我们可以在配置文件中配置日期格式化的规则,如果我们没配,会使用SpringBoot默认的日期格式。

  • application.yaml
# 自定义日期格式化
spring.mvc.date-format=yyyy-MM-dd

SpringBoot:模板引擎 thymeleaf、ContentNegotiatingViewResolver、格式化转换器的更多相关文章

  1. 8.SpringBoot 模板引擎 Thymeleaf

    1.模板引擎原理 JSP.Velocity.Freemarker.Thymeleaf 都是模板引擎.SpringBoot推荐的Thymeleaf:语法更简单,功能更强大: Thymeleaf模板引擎 ...

  2. Spring Boot (四)模板引擎Thymeleaf集成

    一.Thymeleaf介绍 Thymeleaf是一种Java XML / XHTML / HTML5模板引擎,可以在Web和非Web环境中使用.它更适合在基于MVC的Web应用程序的视图层提供XHTM ...

  3. 新一代Java模板引擎Thymeleaf

    新一代Java模板引擎Thymeleaf-spring,thymeleaf,springboot,java 相关文章-天码营 https://www.tianmaying.com/tutorial/u ...

  4. SpringBoot系列:Spring Boot使用模板引擎Thymeleaf

    一.Java模板引擎 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档. 在jav ...

  5. SpringBoot入门系列(四)整合模板引擎Thymeleaf

    前面介绍了Spring Boot的优点,然后介绍了如何快速创建Spring Boot 项目.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/ ...

  6. SpringBoot入门:新一代Java模板引擎Thymeleaf(理论)

    Spring Boot 提供了spring-boot-starter-web来为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及SpringMVC的 ...

  7. springboot:Java模板引擎Thymeleaf介绍

    Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎.类似JSP,Velocity,FreeMaker等,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用 ...

  8. 模板引擎Thymeleaf

    1.Thymeleaf简介 Thymeleaf 是一个跟 Velocity.FreeMarker 类似的模板引擎,它可以完全替代 JSP .相较与其他的模板引擎,它有如下三个极吸引人的特点 Thyme ...

  9. HTML5模板引擎 Thymeleaf 教程(转)

    原文:http://www.open-open.com/lib/view/open1383622135586.html Thymeleaf是一个XML/XHTML/HTML5模板引擎,可用于Web与非 ...

随机推荐

  1. mysql的事务四个特性以及事务的四个隔离级别

    一.事务四大属性 分别是原子性.一致性.隔离性.持久性. 1.原子性(Atomicity) 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,因此事务的操作如果成功就必须要完全应用到数据库, ...

  2. 【python实现卷积神经网络】全连接层实现

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  3. stand up meeting 12-14

    今日更新: 项目的refactor部分均已经基本完成.答题界面和结果展示界面与code hunters team项目的merge部分也已经完成. 当然在这其中我们也遇到了一个小问题,在背单词模块中的词 ...

  4. Bi-shoe and Phi-shoe LightOJ - 1370

    欧拉函数. 欧拉函数打表模板: #define maxn 3000010 int p[maxn]; void oula(){ int i,j; ; i<=maxn; i++) p[i]=i; ; ...

  5. 2. js的异步

    1. 回掉2. promise3. Generator4. Async/await

  6. LeetCode466. Count The Repetitions

    题目链接 传送门 题意 定义一个特殊的串, 现在给出串S1和S2的参数, 问: S2最多可以多少个连接起来扔是S1的子序列, 求出这个最大值 解题思路 注意s1与S1的区别, 可以去看题目描述, 预处 ...

  7. Spark RDD----pyspark第四次作业

    1.pyspark交互式编程 查看群里发的“data01.txt”数据集,该数据集包含了某大学计算机系的成绩,数据格式如下所示: Tom,DataBase,80 Tom,Algorithm,50 To ...

  8. git、gitLab、github区别

    git是一种版本控制系统,是一个命令.一种工具 gitlib是用于实现git功能的开发库 github是一个基于git实现的在线代码仓库,是一个网站,支持几乎所有git操作,可用于托管代码 gitla ...

  9. 2019-2020-1 20199325《Linux内核原理与分析》第九周作业

    第九周作业要求: 理解Linux系统中进程调度的时机,可以在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否准确: 使用gdb跟踪分析一个sc ...

  10. linux uniq 命令实用手册

    Linux uniq 命令用于处理文本内容中的重复行. 这里我们只介绍其常用参数,其完整用法可参见man uniq. 例如,我们有如下文件内容: >>> cat log.txt __ ...