• 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

  • 相关阅读:
    快排原理讲解
    Kafka原理详解
    java中的基本数据类型转换
    centos7关闭防火墙
    安装Linux基本工具
    Kibana笔记
    虚拟机配置net模式
    2019-10-12,html+php+mysql简单留言板,作业
    2019-10-11:渗透测试,基础学习,php+mysql连接,笔记
    2019-10-10:渗透测试,基础学习,mysql语法基础,笔记
  • 原文地址:https://www.cnblogs.com/yanxiaoge/p/10804696.html
Copyright © 2020-2023  润新知