前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot集成Thymeleaf模板引擎

SpringBoot集成Thymeleaf模板引擎

作者头像
SmileNicky
发布于 2019-03-04 02:23:35
发布于 2019-03-04 02:23:35
63300
代码可运行
举报
文章被收录于专栏:Nicky's blogNicky's blog
运行总次数:0
代码可运行

简单介绍 目前在JavaEE领域有几中比较常用的模板引擎,分别是Jsp、Velocity、Freemarker、Thymeleaf,对Freemark语法不是特别熟悉,不过对于前端页面渲染效率来说,jsp其实还是最快的,Velocity次之。Thymeleaf虽然渲染效率不是很快,但是语法方面是比较轻巧的,Thymeleaf语法比Velocity轻巧,但是渲染效率不如Velocity

maven配置 因为引入了SpringBoot的parent工程,所以不需要写版本号

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- Themeleaf -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

application.yml配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#添加Thymeleaf配置
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML5
    encoding: UTF-8
    content-type: text/html

application.yml:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server:
  port: 8081
#logging:
#  config: classpath:logback_spring.xml.bat
#  level:
#    com.muses.taoshop: debug
#  path: /data/logs

spring:
  datasource:

    # 主数据源
    shop:
      url: jdbc:mysql://127.0.0.1:3306/taoshop?autoReconnect=true&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
      username: root
      password: root

    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    # 连接池设置
    druid:
      initial-size: 5
      min-idle: 5
      max-active: 20
      # 配置获取连接等待超时的时间
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      # Oracle请使用select 1 from dual
      validation-query: SELECT 'x'
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      # 打开PSCache,并且指定每个连接上PSCache的大小
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      filters: stat,wall,slf4j
      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 合并多个DruidDataSource的监控数据
      use-global-data-source-stat: true

#  jpa:
#    database: mysql
#    hibernate:
#      show_sql: true
#      format_sql: true
#      ddl-auto: none
#      naming:
#        physical-strategy: org.hibernate.boot.entity.naming.PhysicalNamingStrategyStandardImpl

#  mvc:
#    view:
#      prefix: /WEB-INF/jsp/
#      suffix: .jsp

  #添加Thymeleaf配置
  thymeleaf:
    cache: false
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML5
    encoding: UTF-8
    content-type: text/html

  #Jedis配置
#  jedis :
#    pool :
#      host : 127.0.0.1
#      port : 6379
#      password : redispassword
#      timeout : 0
#      config :
#        maxTotal : 100
#        maxIdle : 10
#        maxWaitMillis : 100000

添加html文件 在resources资源文件夹下面新建一个templates文件夹,所有的html文件都丢在这里,静态资源文件也丢在resources资源文件夹下面

新建一个html文件,然后注意加上<html xmlns:th="http://www.thymeleaf.org">

注意Thymeleaf语法要求比较严格 <meta charset="utf-8" >,不如这样写是不可以的,必须加上斜杠的,<meta charset="utf-8" />

Thymeleaf简单例子

遍历后台数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!--最新上架-->
        <div class="first-pannel clearfix">
            <div class="index-f clearfix">
                <h3 class="index-f-head"> 最新上架 <span>每天都有上新,每天都有惊喜</span> </h3>
                <div class="index-f-body">
                    <div class="top-sales newProduct">
                        <ul class="top-sales-list clearfix">
                            <li class="top-sales-item newProduct" th:each="item : ${items}">
                                <p class="item-img"> <a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}"><img th:src="@{${item.imgPath}}" /></a> </p>
                                <p class="item-buss"><a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}"></a></p>
                                <p class="item-name spec"><a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}" th:text="${item.itemName}"></a></p>
                                <p class="item-price spec"><em th:text="${item.mPrice}"></em></p>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <!--最新上架//-->

引入文件 Thymeleaf引入另外一个html文件可以使用th:replace或者th:include,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!--topBar-->
    <div class="topBar" th:replace="/top_bar :: .topBar"></div>
    <!--//topBar-->
    <!--headerMain-->
    <div class="headerMain layout clearfix" th:replace="/header_main :: .headerMain"></div>
    <!--//headerMain-->
    <!--headerNav-->
    
    <div class="headerNav" th:replace="/index_header_nav :: .headerNav"></div>
    <!--//headerNav-->

Img便签src

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 <img th:src="@{/static/images/rachange_ad.jpg}" />
链接<a>便签
代码语言:javascript
代码运行次数:0
运行
复制

静态资源使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<link th:href="@{/static/css/public.css}" rel="stylesheet" type="text/css" />
    <link th:href="@{/static/css/index.css}" rel="stylesheet" type="text/css" />
    <script type="text/javascript" th:src="@{/static/js/jquery-1.3.2.min.js}"></script>
    <script type="text/javascript" th:src="@{/static/js/html5.js}"></script>
    <script type="text/javascript" th:src="@{/static/js/popbox.js}"></script>

给出一个html页面例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8" />
    <title>电商门户网站</title>
    <link th:href="@{/static/css/public.css}" rel="stylesheet" type="text/css" />
    <link th:href="@{/static/css/index.css}" rel="stylesheet" type="text/css" />
    <script type="text/javascript" th:src="@{/static/js/jquery-1.3.2.min.js}"></script>
    <script type="text/javascript" th:src="@{/static/js/html5.js}"></script>
    <script type="text/javascript" th:src="@{/static/js/popbox.js}"></script>
    <style type="text/css">
        .item-list { display: none; position: absolute; width: 705px; min-height: 200px; _height: 200px; background: #FFF; left: 198px; box-shadow: 0px 0px 10px #DDDDDD; border: 1px solid #DDD; top: 3px; z-index: 1000000; }
        /* Remove Float */
        .clear { display: block; height: 0; overflow: hidden; clear: both; }
        .clearfix:after { content: '\20'; display: block; height: 0; clear: both; }
        .clearfix { *zoom:1;
        }
        .hover { position: relative; z-index: 1000000000; background: #FFF; border-color: #DDD; border-width: 1px 0px; border-style: solid; }
    </style>

</head>
<body>
<!--header-->
<header class="header">
    <!--topBar-->
    <div class="topBar" th:replace="/top_bar :: .topBar"></div>
    <!--//topBar-->
    <!--headerMain-->
    <div class="headerMain layout clearfix" th:replace="/header_main :: .headerMain"></div>
    <!--//headerMain-->
    <!--headerNav-->
    
    <div class="headerNav" th:replace="/index_header_nav :: .headerNav"></div>
    <!--//headerNav-->
</header>
<!--//header-->
<!--container-->
<div class="container">
    <div class="layout clearfix">
        <!--banner-->
        <div class="banner">
            <div class="banner-img">
                <ul>
                    <li><a href="#"><img width="727" height="350" th:src="@{/static/images/banner_970x355.jpg}" /></a></li>
                    <li><a href="#"><img width="727" height="350" th:src="@{/static/images/banner_970x355.jpg}" /></a></li>
                    <li><a href="#"><img width="727" height="350" th:src="@{/static/images/banner_970x355.jpg}" /></a></li>
                </ul>
            </div>
            <ul class="banner-btn">
                <li class="current"></li>
                <li></li>
                <li></li>
            </ul>
        </div>
        <!--//banner-->
        <!--快捷充值-->
        <div class="index-fast-recharge">
            <div class="recharge-body">
                <div class="recharge-head">
                    <h2><em class="icon-phone"></em>话费充值</h2>
                </div>
                <div class="recharge-con">
                    <div class="recharge-form">
                        <p>
                            <label class="name">手机号:</label>
                            <input placeholder="支持电信" type="text" class="text-box" />
                        </p>
                        <p>
                            <label class="name">充值方式:</label>
                            <label>
                                <input type="radio" class="rd" />
                                电信充值卡</label>
                            <label>
                                <input type="radio" class="rd" />
                                银行卡</label>
                        </p>
                        <div class="recharge-sub-btn"> <a href="#" class="btn btn-red">立即充值</a> </div>
                    </div>
                    <div class="recharge-ad"> <img th:src="@{/static/images/rachange_ad.jpg}" /> </div>
                </div>
            </div>
        </div>
        <!--//快捷充值-->
        <div class="clearfix"></div>
        <!--最新上架-->
        <div class="first-pannel clearfix">
            <div class="index-f clearfix">
                <h3 class="index-f-head"> 最新上架 <span>每天都有上新,每天都有惊喜</span> </h3>
                <div class="index-f-body">
                    <div class="top-sales newProduct">
                        <ul class="top-sales-list clearfix">
                            <li class="top-sales-item newProduct" th:each="item : ${items}">
                                <p class="item-img"> <a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}"><img th:src="@{${item.imgPath}}" /></a> </p>
                                <p class="item-buss"><a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}"></a></p>
                                <p class="item-name spec"><a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}" th:text="${item.itemName}"></a></p>
                                <p class="item-price spec"><em th:text="${item.mPrice}"></em></p>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <!--最新上架//-->
    </div>
</div>
<!--//container-->
<!--footer-->
<footer class="footer" th:replace="footer :: .footer"></footer>
<!--//footer-->

<script type="text/javascript">
    //banner
    $(document).ready(function(){
        var demo = $(".banner");
        var btn = $(".banner-btn li");
        var slide = $(".banner-img ul");
        var slideItem = slide.find("li");
        var c = 0, speed = 4000 , t;
        btn.each(function(number){
            $(this).click(function(){
                $(this).addClass("current").siblings().removeClass("current");
                slide.animate({"left":-slideItem.width()*number},300);
                c = number;
            });
        });

        if(btn.size()>1){
            autoSlide();
        }

        function timedCount()
        {
            c = c + 1;
            if(c>=btn.size())c = 0;
            btn.eq(c).click();
        }

        function autoSlide(){
            t = setInterval(function(){timedCount();},speed);
        }
        //鼠标移入停止播放
        demo.mouseover(function(){
            clearInterval(t);
        });
        demo.mouseout(function(){
            autoSlide();
        });
    });
</script>
</body>
</html>

代码取自个人的开源项目:https://github.com/u014427391/taoshop,有需要可以参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年02月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
pnpm + workspace + changesets 构建你的 monorepo 工
关于这些问题,在之前的一篇介绍 lerna 的文章中已经详细介绍过,感兴趣的同学可以再回顾下。
astonishqft
2022/08/31
5.2K0
pnpm + workspace + changesets 构建你的 monorepo 工
前端工程化实践:Monorepo与Lerna管理
前端工程化实践中,Monorepo(单仓库)管理和Lerna是两种流行的方式,用于大型项目或组件库的组织和版本管理。
天涯学馆
2024/06/14
3470
基于 Lerna 管理 packages 的 Monorepo 项目最佳实践
对于维护过多个package的同学来说,都会遇到一个选择题,这些package是放在一个仓库里维护还是放在多个仓库里单独维护,本文通过一个示例讲述了如何基于Lerna管理多个package,并和其它工具整合,打造高效、完美的工作流,最终形成一个最佳实践
杨振涛
2019/08/06
3.1K0
基于 Lerna 管理 packages 的 Monorepo 项目最佳实践
大仓实践录:Lerna/NPM/Yarn Workspace 方案组合和性能对比
仓就是仓库(repository,简称 repo)。通常我们使用多个仓库(简称多仓,multi-repo)来管理项目代码,也就是每个仓库负责一个模块或包的编码、构建、测试和发布,代码规模相对较小,所以也称为小型规模仓库(简称小仓)。而单一(mono)仓库(简称单仓,mono-repo)是指在一个仓库中管理多个模块或包,当代码规模达到一定程度后可称为大型规模仓库(简称大仓),至于这个程度大小并没有明确定义,通常说的大仓可理解为就是单仓。
CodecWang
2021/12/07
5.2K0
大仓实践录:Lerna/NPM/Yarn Workspace 方案组合和性能对比
突破项目瓶颈:2024 年 Monorepo 工具选择和实践
原文地址:https://juejin.cn/post/7342360674151858202
winty
2024/03/18
2.7K0
突破项目瓶颈:2024 年 Monorepo 工具选择和实践
Vue3源码01 : 代码管理策略-monorepo
从定义中可以知道,monorepo是一种策略,该策略的具体内容是:多个项目存储在同一个代码仓库中。采用一种策略,肯定是因为该策略具备一些优点。当然,也要认清其缺点。从下面这张图中,我们可以看出,项目代码的组织策略是在实践中诞生,不断发展变化的。
杨艺韬
2022/09/27
1.3K0
Vue3源码01 : 代码管理策略-monorepo
lerna最佳实践
在介绍我们今天的主角 lerna 之前,首先了解下什么是 multirepo ?什么是 monorepo ?
astonishqft
2022/05/10
2K0
lerna最佳实践
带你了解并实践monorepo和pnpm,绝对干货!熬夜总结!
简单来说就是,将多个项目或包文件放到一个git仓库来管理。 目前比较广泛应用的是yarn+lerna的方式实现monorepo的管理。 一个简单的monorepo的目录结构类似这样:
winty
2023/08/23
7.5K0
带你了解并实践monorepo和pnpm,绝对干货!熬夜总结!
lerna + dumi + eslint多包管理实践
在开发大型项目时, 我们通常会遇到同一工程依赖不同组件包, 同时不同的组件包之间还会相互依赖的问题, 那么如何管理组织这些依赖包就是一个迫在眉睫的问题.
玖柒的小窝
2021/10/05
4200
lerna + dumi + eslint多包管理实践
现代前端工程为什么越来越离不开 Monorepo?
随着前端工程日益复杂,某些业务或者工具库通常涉及到很多个仓库,那么时间一长,多个仓库开发弊端日益显露,由此出现了一种新的项目管理方式——Monorepo。本文主要以 Monorepo 的概念、MultiRepo的弊端、Monorepo 的收益以及Monorepo 的落地这几个角度来认识和学习一下 Monorepo,文末会有思考题,欢迎大家来踊跃讨论。
用户3806669
2021/03/27
1.6K0
读完 Vue 发布源码,小姐姐回答了 leader 的提问,并优化了项目发布流程~
这一期阅读的是 Vue3 源码中的 script/release.js 代码,也就是 Vue.js 的发布流程。在上一期源码阅读中从 .github/contributing.md[1] 了解到 Vue.js 采用的是 monorepo 的方式进行代码的管理。
若川
2021/09/07
1.2K0
基于pnpm + lerna + typescript的最佳项目实践 - 理论篇
为什么叫pnpm?是因为pnpm作者对现有的包管理工具,尤其是npm和yarn的性能比较特别失望,所以起名叫做perfomance npm,即pnpm(高性能npm)
Nealyang
2022/04/11
3.6K0
基于pnpm + lerna + typescript的最佳项目实践 - 理论篇
lerna入门指南
一.定位 Lerna is a tool that optimizes the workflow around managing multi-package repositories with git
ayqy贾杰
2019/06/12
1.6K0
大仓实践录:Lerna/NPM/Yarn Workspace 方案组合和性能对比
仓就是仓库(repository,简称 repo)。通常我们使用多个仓库(简称多仓,multi-repo)来管理项目代码,也就是每个仓库负责一个模块或包的编码、构建、测试和发布,代码规模相对较小,所以也称为小型规模仓库(简称小仓)。而单一(mono)仓库(简称单仓,mono-repo)是指在一个仓库中管理多个模块或包,当代码规模达到一定程度后可称为大型规模仓库(简称大仓),至于这个程度大小并没有明确定义,通常说的大仓可理解为就是单仓。
CodecWang
2023/11/17
2K0
大仓实践录:Lerna/NPM/Yarn Workspace 方案组合和性能对比
使用Yarn与Lerna管理monorepo
Yarn workspace 是 Yarn 提供的 monorepo 下,管理依赖的机制。对代码仓库下,多个 package 的依赖,进行管理:将共同的依赖,做 hosting(提升)。这样,可以防止 package 中的包重复安装。
我是leon
2022/03/11
1.4K0
基于 lerna 实现 Monorepo 项目管理
目前来讲,Lerna 作为 JavaScript项目的多包管理器,已经是比较成熟,并已被现代企业所验证,因此接下来将逐步搭建一个基于 Lerna[1] 的 Monorepo 管理环境,希望可以帮助大家在各司业务中落地并实现降本提效。
小东同学
2022/07/29
1.8K0
基于 lerna 实现 Monorepo 项目管理
多包依赖管理--Lerna
Lerna是一个使用git和npm来处理多包依赖管理的工具,利用它能够自动帮助我们管理各种模块包之间的版本依赖关系。可以让你在主项目下管理多个子项目,从而解决了多个包互相依赖,且发布时需要手动维护多个包的问题。它属于monorepo类型,当你的项目有相关联时最好使用monorepo方式进行管理。
刘亦枫
2020/10/27
4.8K0
基于 lerna 的多包 JavaScript 项目搭建维护笔记
将大型代码仓库分割成多个独立版本化的 软件包(package)对于代码共享来说非常有用。但是,如果某些更改 跨越了多个代码仓库的话将变得很 麻烦 并且难以跟踪,并且, 跨越多个代码仓库的测试将迅速变得非常复杂。
用户1250838
2021/07/30
7970
lerna + dumi + eslint多包管理实践
在开发大型项目时, 我们通常会遇到同一工程依赖不同组件包, 同时不同的组件包之间还会相互依赖的问题, 那么如何管理组织这些依赖包就是一个迫在眉睫的问题.
徐小夕
2021/10/14
1.3K0
基于 Yarn 的 Monorepo 实践
几年前工作中整过几个 SDK 仓库,当时 SDK 库逻辑还比较简单,工程设计也不复杂: ESLint+Prettier+GitHook Rollup 打包 npm 私有仓库搭建 随即发包复用就解决了。 随着时间的推移,SDK 库为了兼容各个端、完善开发体验实现各种配套的调试工具等等逐渐变得复杂,之前简单的工程能力要实现源码插件化、分包发布、定制化构建等等能力会比较痛苦: 简单目录隔离划分模块 手动多次更新目录 package.json 版本来发包 多个端代码复用一个 tsconfig.json,存在端限制(
用户1097444
2022/06/29
1.7K0
基于 Yarn 的 Monorepo 实践
推荐阅读
相关推荐
pnpm + workspace + changesets 构建你的 monorepo 工
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档