首页 > 编程语言 > 详细

SpringBoot:模板引擎 thymeleaf、ContentNegotiatingViewResolver、格式化转换器

时间:2020-04-19 11:33:35      阅读:63      评论:0      收藏:0      [点我收藏+]

模板引擎 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、格式化转换器

原文:https://www.cnblogs.com/rainszj/p/12730712.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!