Spring Boot----静态资源映射以及集成 Thymeleaf 模板引擎

 静态资源映射:

1、静态资源映射规则

 查看 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration 添加资源映射这段代码

@Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
                return;
            }
            Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
            CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
            //第一种映射规则("/webjars")
              if (!registry.hasMappingForPattern("/webjars/**")) {
                customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                        .addResourceLocations("classpath:/META-INF/resources/webjars/")
                        .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
            }
            String staticPathPattern = this.mvcProperties.getStaticPathPattern();
            //第二种映射规则("/")
              if (!registry.hasMappingForPattern(staticPathPattern)) {
                customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                        .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                        .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
            }
        } 

1.1第一种映射规则:以/webjars/的请求

比如 http://localhost:8080/webjars/jquery/3.4.1/jquery.js,springboot会去/META-INF/resources/webjars/获取资源

1.1.1我们需要通过maven来添加静态资源

 

 

1.1第二种映射规则:以/**的请求 

如果没有被处理(RequestMapping),就会去这些目录去找资源

classpath:/META-INF/resources/     //目录需要自己建
classpath:/resources/              //目录需要自己建
classpath:/static/                 //spring boot 帮我们建好了
classpath:/public/                 //目录需要自己建
/                                  //当前项目的根路径

  

1.2 对于localhost:8080/ 是如何映射到 index.html?

源码

@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
    WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
            new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
            this.mvcProperties.getStaticPathPattern());
    welcomePageHandlerMapping.setInterceptors(getInterceptors());
    return welcomePageHandlerMapping;
}

1.3 所有的**/favicon.ioc 都是在静态资源找

1.4 修改默认的静态资源路径配置(application.properties)

spring.resources.static-locations=classpath:/,classpath:/hellow/

 

 模板引擎:

 

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

  • Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板 + 数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示。
  • Thymeleaf 开箱即用的特性。它提供标准和 Spring 标准两种方言,可以直接套用模板实现 JSTL、 OGNL 表达式效果,避免每天套模板、改 JSTL、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
  • Thymeleaf 提供 Spring 标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能。

如果希望以 Jar 形式发布模块则尽量不要使用 JSP 相关知识,这是因为 JSP 在内嵌的 Servlet 容器上运行有一些问题 (内嵌 Tomcat、 Jetty 不支持 Jar 形式运行 JSP,Undertow 不支持 JSP)。所以需要使用Thymeleaf类似的模板引擎。

Spring Boot 提供了大量模板引擎,包括:

  • FreeMarker
  • Groovy
  • Mustache
  • Thymeleaf
  • Velocity
  • Beetl

1.使用

源码:org.springframework.boot.autoconfigure.thymeleaf

1.1 意思叫我们将html页面放到templates目录下

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
	private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
	public static final String DEFAULT_PREFIX = "classpath:/templates/";
     //只用将.html文件放到classpath:/templates/目录下,thymeleaf就能解析了
	public static final String DEFAULT_SUFFIX = ".html";
}

2.1 创建项目

1、创建项目的时候添加 Thymeleaf 配置

如果已经创建完成项目(创建项目的时候没有导入thymeleaf),在pom.xml 手动添加依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

2、在pom.xml 添加依赖(不知道干嘛的,不添加也没事)

<dependency>
    <groupId>net.sourceforge.nekohtml</groupId>
    <artifactId>nekohtml</artifactId>
    <version>1.9.22</version> //可以删除
</dependency>  

3、在 application.yml 中配置 Thymeleaf

spring:
  thymeleaf:
    cache: false #开发时关闭缓存,不然没法看到实时页面
    mode: LEGACYHTML5 #用非严格的 HTML5
    encoding: UTF-8
    servlet:
      content-type: text/html

4、添加 thymeleaf 命名空间

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

5、测试

controller

@RequestMapping(value = "",method = RequestMethod.GET)
public String index(Model model){
        model.addAttribute("user","zy");
        return "index";
}

html

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<span th:text="${user}">姓名</span>
</body>
</html>

 

2.Thymeleaf语法

注意,使用thymeleaf必须经过模板解析才可以,如果直接访问的静态资源(html),在里面使用thymeleaf语法不生效

参考:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

1、th:text 可以用于替换原来的值

<div id="1" th:id="${id}" th:text="${text}">文本</div>

th全部语法

 

 

2、表达式语法

Simple expressions:
  Variable Expressions: ${...}              变量表达式
  Selection Variable Expressions: *{...}    选择表达式,功能上和${}一样,可以配合th:object="${session.user}使用,具体可以看官方文档中的例子
  Message Expressions: #{...}               获取国际化内容
  Link URL Expressions: @{...}              定义url,使用@{/x/xx} / 前面会自动补全项目名字
  Fragment Expressions: ~{...}              片段引用表达式
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,…
Text operations:(文本操作)
  String concatenation: +
  Literal substitutions: |The name is ${name}|
Arithmetic operations:(数学运算)
  Binary operators: +, -, *, /, %
  Minus sign (unary operator): -
Boolean operations:(布尔运算)
  Binary operators: and, or
  Boolean negation (unary operator): !, not
Comparisons and equality:(比较运算)
  Comparators: >, <, >=, <= (gt, lt, ge, le)
  Equality operators: ==, != (eq, ne)
Conditional operators:(条件运算)
  If-then: (if) ? (then)
  If-then-else: (if) ? (then) : (else)
  Default: (value) ?: (defaultvalue)
Special tokens:(特殊操作)
  No-Operation: _

  

3.thymeleaf公共元素抽取

参考:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#template-layout

抽取公共片段,任何thml页面

    <div th:fragment="copy">
      © 2011 The Good Thymes Virtual Grocery
    </div>

引入公共片段方式1(footer是模板名字(从 footer.html 抽取的))

模板名:: 片段名

根据实际情况选择下面的哪一种,具体区别参考官方文档(最好写成这中方法~{footer :: #copy-section}",在行类写法中[[~{}]],一定需要带上~{})

<body>

  <div th:insert="footer :: copy"></div>

  <div th:replace="footer :: copy"></div>

  <div th:include="footer :: copy"></div>
  
</body>

引入公共片段方式2(footer是模板名字(从 footer.html 抽取的))

模板名:: 选择器

<body>
  <div th:insert="~{footer :: #copy-section}"></div>  //引入id是copy-section的一个标签,不需要定义 th:fragment="copy"
</body>

 

4.点击不同的侧边栏,会出现高亮

 

1、将公共的部分抽取出来单独放到一个html里面(bar.html)

 

 

2、引入这个bar.htmtl的时候传入参数(引入的bar,看到有emps,就会在某一个li中高亮)

 

 

 

4.格式化日期

参考:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#appendix-b-expression-utility-objects

${#dates.format(date, 'dd/MMM/yyyy HH:mm')}

5、url拼接

<a href="" th:href="@{/userdelete/}+${user.value.id}">
<a th:attr="href=@{/userdelete/}+${user.value.id}">

6、表单回显 

<form>
    <!--普通值的替换-->
    <input type="text" name="username" th:value="${user.username}">
    <!--单选按钮,注意user.gender的类型-->
    <input type="radio" name="gender" value="1" th:checked="${user.gender=='1'}">
    <input type="radio" name="gender" value="0" th:checked="${user.gender}=='0'">
    <!--单选框-->
    <select name="select">
        <option th:each="dept:${departments}" th:text="${dept.value.name}" th:selected="${dept.key==user.department.id}"></option>
    </select>
    <!--日期-->
    <input type="text"  name="date" th:value="${#dates.format(user.birth, 'yyyy/MM/dd')}">
</form>

注意,如果取不到值,就会报错,所以配置@ModelAttribute 使用

@ModelAttribute
    public void init(@RequestParam(value = "id",required = false) Integer  id, Model model){
        User user = null;
        if (id!=null){
            user = userService.selectUserByid(id);
        }else{
            user = new User();
            Department department = new Department();
            user.setDepartment(department);
        }
        model.addAttribute("user",user);
        HashMap<Integer, Department> department = userService.selectalldepartment();
        model.addAttribute("departments",department);
    }

7、内联表达式

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#expression-inlining

  javascript中使用

	<script type="text/javascript" th:inline="javascript">
		$(".in li[class='"+[[${activeUrl}]]+"']").addClass("active");
	</script>

  css使用

<style th:inline="css">
  ...
</style>

8、条件判断

如果要实现if else if else 判断表达式,在thymeleaf要使用th:switch代替,th:case="*"表示默认,需写在最后

9、在html中获取数据session、request参数的值

  Request参数

    假设请求的url为:/user/get?id=12

    1、访问参数id可以使用param前缀,例如:${param.id!=null}检查是否有参数id;

    2、参数是一个数组,因为它可以多值比如?id=a&name=test,所以可以采用下标的方式访问,例如:

<p th:text="${param.q[0]}" th:unless="${param.q == null}">11</p>

  3、还有一种访问方式是使用#httpServletRequest对象,可以直接进入javax.servlet.http.HttpServletRequest对象,例如:

<p th:text="${#httpServletRequest.getParameter('id')} th:unless="${#httpServletRequest.getParameter('id') == null}">11</p>

  Session属性

    比如后台为session添加了一个sessionValue属性,和Request参数访问方式类似,这里使用session前缀:

<div th:text="${session.sessionValue}">[...]</div>

    同样的,还可以使用#httpSession方式访问,它直接进入javax.servlet.http.HttpSession对象。

  ServletContext属性

    1、ServletContext属性可以在request和session中共享,未来访问ServletContext属性,可以使用application前缀:

      比如后台为ServletContext添加了一个myContextAttribute属性,那么我们可以这样访问:<div th:text="${application.myContextAttribute}">[...]</div>

    2、<div th:text="${application.size()}">33</div> 将返回application的数量;

      3、输出其所有键值对:

<div th:each="attr:${application.keySet()}">
    <span th:text="${attr}">key</span>
    <span th:text="${application.get(attr)}">value</span>
</div>

  Spring beans

    Thymeleaf可以通过@beanName访问Spring应用上下文中注册的bean,如<div th:text="${@urlService.getApplicationUrl()}">...</div>
    在这个例子中,@urlService就是在上下文中注册的Spring Bean的名字:

10、数字格式化

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#numbers

 

posted @ 2019-05-03 11:45  小名的同学  阅读(1076)  评论(0编辑  收藏  举报