Thymeleaf简介
入门freemarker与Thymeleaf的对比配置 运行原理
展示数据
小案例----->> th 操作属性 标准表达式
条件表达式数据访问方式内置对象可选参数 Thymeleaf遍历信息
运算符
算数运算符关系运算符逻辑运算符条件运算符条件运算符 链接网址模板模板
定义和引用片段 模板引擎对比
Thymeleaf简介Thymeleaf是一个现代的服务器端 Java 模板引擎,适用于 Web 和独立环境。
Thymeleaf 的主要目标是为您的开发工作流程带来优雅的自然模板— HTML 可以在浏览器中正确显示,也可以作为静态原型工作,从而在开发团队中实现更强的协作。
Thymeleaf 具有 Spring framework 模块、大量与您最喜爱的工具集成,以及插入您自己的功能的能力,是现代 HTML5 JVM Web 开发的理想选择 — 尽管它可以做的还有很多。
更多描述请转官网
---------------------摘自官网描述--------------------
入门就是先整一个Thymeleaf程序
参照freemarker的整合,这里将freemarker的启动器换成Thymeleaf
依赖的变动就这么一点;
org.springframework.boot spring-boot-starter-thymeleaf 2.6.2
这里选择最新版本的依赖,如果出现一些其他问题,后面再去解决;
freemarker与Thymeleaf的对比 配置详细官网配置请见spring官网
源码是这样写的:
public class GTVGApplication {
...
private final TemplateEngine templateEngine;
...
public GTVGApplication(final ServletContext servletContext) {
super();
ServletContextTemplateResolver templateResolver =
new ServletContextTemplateResolver(servletContext);
// HTML is the default mode, but we set it anyway for better understanding of code
templateResolver.setTemplateMode(TemplateMode.HTML);
// This will convert "home" to "/WEB-INF/templates/home.html"
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
// Template cache TTL=1h. If not set, entries would be cached until expelled
templateResolver.setCacheTTLMs(Long.valueOf(3600000L));
// Cache is set to true by default. Set to false if you want templates to
// be automatically updated when modified.
templateResolver.setCacheable(true);
this.templateEngine = new TemplateEngine();
this.templateEngine.setTemplateResolver(templateResolver);
...
}
}
以上默认配置表示 thymeleaf使用UTF-8编码,
访问时前缀template,后缀为html,
即直接转发或重定向到这个文件即可;
直接访问这个文件不可以么?
还真不可以,这个跟freemarker一致,
运行原理Thymeleaf在Spring Boot项目中放入到resources/templates中。这个文件夹中的内容是无法通过浏览器URL直接访问的(和WEB-INF效果一样),所有Thymeleaf页面必须先走控制器。
模板解析器
//模板解析器是实现来自 Thymeleaf API 的接口的对象,全限定名称为:org.thymeleaf.templateresolver.ITemplateResolver
public interface ITemplateResolver {
...
public TemplateResolution resolveTemplate(
final IEngineConfiguration configuration,
final String ownerTemplate, final String template,
final Map templateResolutionAttributes);
}
为了处理数据,并适应国际化的需求,模板引擎在获得request,response,还需要获得请求来自的地区;
public class HomeController implements IGTVGController {
public void process(
final HttpServletRequest request, final HttpServletResponse response,
final ServletContext servletContext, final ITemplateEngine templateEngine)
throws Exception {
WebContext ctx =
new WebContext(request, response, servletContext, request.getLocale());
templateEngine.process("home", ctx, response.getWriter());
}
}
展示数据准备好上下文对象后,现在我们可以告诉模板引擎使用上下文处理模板(按其名称),并将其传递给响应编写器,以便可以将响应写入它;
友情提醒----在展示数据之前还需要引入一个命名空间
因为我们在表单中使用的这些非标准属性是 HTML5 规范所不允许的。
1,Thymeleaf中表达式必须依赖标签而不能单独使用
2,标准变量表达式一般在开始标签中,以 th开头
3,语法为:
4,表达式中可以通过${}取出域中的值并放入标签的指定位置
5,${}在这里不能单独使用,必须在 th:后面的双引号里使用
比如后端---->>
@Controller
public class ShowController {
@RequestMapping("/goodsinfo")
public String showInfo(Mapmap){
map.put("goodsname","小鸡炖蘑菇");
return "sample";
}
}
前端:
Title
这道菜是"${goodsname}"
html文件中th并没有把规定标签,所以要引入th空间;
注:这里时idea自带的提示,官方建议是引入
xmlns:th="http://www.thymeleaf.org,
**data-th-语法是在 HTML5 中编写自定义属性的标准方法,该语法无需开发人员使用任何命名空间名称;
html源代码
@Controller
public class ShowController {
@RequestMapping("/goodsinfo")
public String showInfo(Mapmap){
map.put("goodsname","小鸡炖蘑菇");
map.put("username","wet");
map.put("colorful","background-color: yellowgreen");
return "sample";
}
}
后端传过来的数据
Title
这道菜是"${goodsname}"
简单总结一下---->
Thymeleaf将后端的数据 用th:*来展现,且只能在前标签中才能生效;
基本书写格式----->>th:标签中属性名="${}"
如果为了更方便区分可以在属性前加 data-th-标签中属性名="$()"
这两种形式是完全等效的,自己习惯哪一种就用哪一种;
以上内容均为白话形式,如有不当之处,还请参阅
Thymeleaf官方文档
namespace-------th可以操作的属性
只要是html能识别的标签中的属性基本就可以;
有一点不太友好的是----1999/xhtml的引入提示会没有提示;
案例—>>
前端传来一个Goods对象
@RequestMapping("/one")
public ModelAndView showone(Map map) {
Goods goodsById = goodsService.findGoodsById(2);
System.out.println(goodsById);
map.put("goods", goodsById);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("sample3");
return modelAndView;
}
}
菜单信息
id: goodsName: price: goodsDesc:
当返回的信息属性带有null时,thymeleaf并不会报错而freemarker会报错;
那如果返回对象为null时----->>
报异常
所以----->>
菜单信息
判断是否为空 id: goodsName: price: goodsDesc:
th:text
文本文本只是在单引号之间指定的字符串。它们可以包含任何字符,但您应该使用 对其中的任何单引号进行转义。’
Now you are looking at a template file.
home.welcome=Welcome to our fantastic grocery store!
Welcome to our grocery store!
Welcome to our grocery store!
前端显示结果
当我们用了text时,会替换事先做好的内容;
数字文本
数字文字就是:数字。
The year is 1492.
In two years, it will be 1494.
布尔文本
true false
...在这个例子中,写在大括号外面,所以是ThymeLeaf照顾它。如果它写在大括号内,那将是OGNL / SpringEL引擎来负责处理,达到的效果是一样的
true 与 false 只能在if中使用;
空文本还可以使用文本:null
文本标记
类似于html中的选择器
数字,布尔和空文本实际上是文本标记的特殊情况。
这些标记允许在标准表达式中进行一些简化。它们的工作方式与文本文本 () 完全相同,但它们只允许使用字母 ( 和 )、数字 ()、方括号 ( 和 )、点 ()、连字符 () 和下划线 ()。所以没有空格,没有逗号等它不需要围绕它们的任何引号。因此,我们可以这样做:
...hello
附加文本文本,无论是文本还是计算变量或消息表达式的结果,都可以使用运算符轻松追加:+
文字替换
文本替换允许轻松格式化包含变量值的字符串
这些替换必须用竖线 () 包围,例如:|
这相当于:
例子
文本替换可以与其他类型的表达式结合使用:
在文本替换中只允许使用变量/消息表达式
设置属性值
此模板开始时是y一个静态原型,而不是 Web 应用程序的模板,如果要实现动态交互,则需要给此表单添加action,
除了输入属性,更改设置它的标签的属性值要用到----th:attr
但是,如果我们想一次设置多个属性呢?XML 规则不允许您在标记中设置属性两次,因此将采用逗号分隔的赋值列表,
![]()
给定所需的消息文件,这将输出:
但是实际上我们会用到类似于 th:text th:title等类似简单的方式来实现,除非在thymeleaf中没有,那么才应该考虑用这种方式;
在thyme中的标签属性---->>>为特定属性设置值
预置和附加属性
thymeleaf
这种预置和附加标签之间的区别---->>thymeleaf1
thymeleaf2
thymeleaf3thymeleaf4
classappend用于向元素添加 CSS 类或样式片段,而不会覆盖现有属性;
attrappend用于添加属性,并不会覆盖哦原来的属性而是在后面追加
styleappend用于追css样式这些属性会将其评估结果附加(后缀)或前缀(前缀)到现有属性值。
固定值布尔属性
HTML具有布尔属性的概念,这些属性没有值,并且一个属性的优先性意味着值是"真的"。在 XHTML 中,这些属性只取 1 个值,即它本身。例如:checked
标准方言包含允许您通过评估条件来设置这些属性的属性,因此,如果计算为 **true,**则该属性将设置为其固定值,如果计算为 false,则不会设置该属性:
肥肠鱼 蒸熊掌
标准表达式
Simple expressions: Variable expressions: ${...} Selection Variable expressions: *{...} Message expressions: #{...} link URL expressions: @{...} Fragment expressions: ~{...} Literals Text literals: , ,…'one text''Another one!' Number literals: , , , ,…0343.012.3 Boolean literals: , truefalse Null literal: null Literal tokens: , , ,…onesometextmain Text operations: String concatenation: + Literal substitutions: |The name is ${name}| Arithmetic operations: Binary operators: , , , , +-*/% Minus sign (unary operator): - Boolean operations: Binary operators: , andor Boolean negation (unary operator): , !not Comparisons and equality: Comparators: , , , (, , , ><>=<=gtltgele) Equality operators: , (, ==!=eqne) Conditional operators: If-then: (if) ? (then) If-then-else: (if) ? (then) : (else) Default: (value) ?: (defaultvalue) Special tokens: No-Operation: _简单表达式: 变量表达式:${...} 选择变量表达式:*{...} 消息表达式:#{...} 链接网址表达式:@{...} 片段表达式:~{...} 文字 文本文本:,,...'one text''Another one!' 数字文字: , , , ,...0343.012.3 布尔文字: ,truefalse 空文本:null 文字标记: , , ,...onesometextmain 文本操作: 字符串串联:+ 文字替换:|The name is ${name}| 算术运算: 二元运算符: , , , , ,+-*/% 减号(一元运算符):- 布尔运算: 二元运算符: ,andor 布尔否定(一元运算符):,!not 比较和平等: 比较器: , , , ( , , ,><>=<=gtltgele) 等运算符: , (,==!=eqne) 条件运算符: 如果-那么:(if) ? (then) 如果-然后-否则:(if) ? (then) : (else) 违约:(value) ?: (defaultvalue) 特殊代币: 无操作:_ 所有这些功能都可以组合和嵌套:条件表达式Onions 2.41 yes 评论--爆发虎 comment/s view
后端—>
@ResponseBody @RequestMapping("/comments") public String comments(Integer GoodsId){ Goods goodsById = goodsService.findGoodsById(GoodsId); return goodsById.getGoodsname(); }th:if 不仅会计算布尔条件。它的功能不至于此,它将按照以下规则计算指定的表达式—>>
If value is not null:
If value is a boolean and is .true
If value is a number and is non-zero
If value is a character and is non-zero
If value is a String and is not “false”, “off” or “no”
If value is not a boolean, a number, a character or a String.
(If value is null, th:if will evaluate to false).反向属性th:unless,我们可以在前面的示例中使用该属性,而不是在OGNL表达式中使用:th:if th:unlessnot
viewth:switch
还有一种方法可以使用Java中的开关结构的等效物有条件地显示内容:/属性集。th:switch 与th:caseUser is an administrator
User is a manager
请注意,只要将一个属性计算为 ,同一开关上下文中的所有其他属性的计算结果为 。th:case true th:case false
默认选项指定为 :th:case="*"
User is an administrator
User is a manager
User is some other thing
案例演示:
Onions 2.41 yes 招牌菜 如果菜名是酸菜鱼则显示招牌菜 评论--爆发虎 comment/s view 数据访问方式第一种----->>
内置对象
${person.father.name}
第二种----->>
${person[‘father’][‘name’]}
第三种,如果是map映射
${person[father’].name}
还可以用
${personsArray[0].name}
还可以调用方法
${person.createCompleteName()}
${person.createCompleteNameWithSeparator(’-’)}#ctx: the context object. 上下文对象 #vars: the context variables. 上下文变量 #locale: the context locale. 位置 #request: (only in Web Contexts) the object.HttpServletRequest请求对象 #response: (only in Web Contexts) the object.HttpServletResponse响应对象 #session: (only in Web Contexts) the object.HttpSession session对象 #servletContext: (only in Web Contexts) the object.ServletContext ServletContext对象这样就可以向jsp中那样,将信息存储在与域对象中然后在取出来,如果可以的话还可以在Thymeleaf中做一些数据处理
除了这些基本对象之外,Thymeleaf还将为我们提供一组实用程序对象,这些对象将帮助我们在表达式中执行常见任务。
#execInfo: information about the template being processed. #messages: methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax. #uris: methods for escaping parts of URLs/URIs #conversions: methods for executing the configured conversion service (if any). #dates: methods for java.util.Date objects: formatting, component extraction, etc. #calendars: analogous to #dates, but for java.util.Calendar objects. #numbers: methods for formatting numeric objects. #strings: methods for String objects: contains, startsWith, prepending/appending, etc. #objects: methods for objects in general. #bools: methods for boolean evaluation. #arrays: methods for arrays. #lists: methods for lists. #sets: methods for sets. #maps: methods for maps. #aggregates: methods for creating aggregates on arrays or collections. #ids: methods for dealing with id attributes that might be repeated一些常用的内置对象案例
1表示整数位至少保持一位(如果不够则补0),COMMA表示, point表示 .部分结果----->>
request:可选参数
session:
application:
可选参数
Not only can variable expressions be written as ${...}, but also as *{...}.两种方式---- 1,${} 2,*{} 星号语法作用 于所选对象上的表达式,而不是整个上下文上的表达式。 如果没有选定的对象,${}和*{}的操作完全相同。例如----->>官方给出的案例
Name: Sebastian.
Surname: Pepper.
Nationality: Saturn.
上述等同于
Name: Sebastian.
Surname: Pepper.
Nationality: Saturn.
实际运用---->>
id: Sebastian
goodsname: Pepper.
price: Saturn.
price: Saturn.
goodsdesc: Saturn.
goodsdesc: Saturn.
goodsdesc: Saturn.
实际上如果没有定义th:object那么*{}与${}达到的效果是一样的;
Thymeleaf遍历信息list
菜品编号 菜品名称 菜品价格 菜品描述 >
直接取Map:
很多时候我们不存JavaBean而是将一些值放入Map中,再将Map存在Model中,我们就需要对Map取值,对于Map取值你可以${Map名['key']}来进行取值。也可以通过 M a p 名 . k e y 取 值 , 当 然 你 也 可 以 使 用 ‘ {Map名.key}取值,当然你也可以使用` Map名.key取值,当然你也可以使用‘{map.get(‘key’)}`(java语法)来取值,完整代码如下:Map
place: feeling: 遍历Map:
如果说你想遍历Map获取它的key和value那也是可以的,这里就要使用和List相似的遍历方法,使用th:each="item:${Map名}"进行遍历,在下面只需使用item.key和item.value即可获得值。完整代码如下:Map遍历
案例—>>
@RequestMapping("/showA") public ModelAndView showA(Mapmap) { List goods = goodsService.showGoods(); ModelAndView modelAndView = new ModelAndView(); Map map1 = new HashMap<>(6); for (Goods g : goods) { map1.put(g.getId().toString(),g); } map.put("goodsMap",map1); modelAndView.setViewName("sample4"); return modelAndView; } @RequestMapping("/removeGoods") public String removeGoods(Integer id){ int i = goodsService.removeInfo(id); return "redirect:showA"; } 菜单
键值 菜品编号 菜品名称 菜品价格 菜品描述 优惠信息 操作 删除 小结---->>
示例中u为迭代遍历。
th:each="element,status:${listinfo}" 其中status表示迭代状态。
1,index:当前迭代器的索引 从0开始
2,count:当前迭代对象的计数 从1开始
3,size:被迭代对象的长度
4,even/odd:布尔值,当前循环是否是偶数/奇数 从0开始
5,first:布尔值,当前循环的是否是第一条,如果是返回true否则返回false
6,last:布尔值,当前循环的是否是最后一条,如果是则返回true否则返回false
索引 序号 总数 偶数索引 基数索引 第一? 最后? 菜品编号 菜品名称 菜品价格 菜品描述 优惠信息
放上官方给出的案例—>>Good Thymes Virtual Grocery Product list
NAME PRICE IN STOCK Onions 2.41 yes 可以迭代的对象,
任何实现的对象java.util.Iterable任何实现 的对象。java.util.Enumeration任何实现的对象,其值将在迭代器返回时使用,而无需在内存中缓存所有值。任何实现java.util.Iterator的对象。迭代映射时,迭代变量将属于 类 。java.util.Mapjava.util.Map.Entry任何数组。任何其他对象都将被视为包含对象本身的单值列表。 运算符 算数运算符
算数运算符
某些算术运算也可用±*/%请注意,这些运算符也可以应用于 OGNL 变量表达式本身(在这种情况下,将由 OGNL 而不是 Thymeleaf 标准表达式引擎执行):
请注意,其中一些运算符存在文本别名:div 即/ mod 即%
关系运算符关系运算符
略
XML 确定不应在属性值中使用 和 符号,因此应将它们替换为相应的符号> 1"> 更简单的替代方法可能是使用其中一些运算符存在的文本别名 逻辑运算符**逻辑运算符** **逻辑运算符**2
0
2
1
1
在最新版的thymeleaf中对&& 与 ||不太 友好,报错了
条件运算符
注意:
条件运算符
像这种空的时候,字符串默认为’’,如果是其他数据则是null条件表达式旨在仅计算两个表达式中的一个,具体取决于计算条件的结果(条件本身是另一个表达式)。
让我们看一个示例片段(引入另一个属性修饰符, ):th:class
... 后端
map.put("ifU",true);hello条件表达式也可以使用括号嵌套:
... Else 表达式也可以省略,在这种情况下,如果条件为 false,则返回 null 值:
... 默认值—>>>
在freemarker中也有默认值的表达方式---->>>>${!''}而在thymeleaf中,默认表达式是一种不带 then 部分的特殊条件值。它等效于某些语言(如Groovy)中存在的Elvis运算符,允许您指定两个表达式:如果计算结果不为null,则使用第一个表达式,但如果计算结果为null,则使用第二个表达式。
例如---->>...Age: 27.
如您所见,运算符是 ,我们在这里使用它来指定名称的默认值(在本例中为文本值),仅当计算结果为 null 时。因此,这等效于:?{age}
Age: 27.
与条件值一样,它们可以在括号之间包含嵌套表达式:
Name: Sebastian
链接网址URL是Web应用程序模板中的一等公民,Thymeleaf标准方言为它们提供了特殊的语法,即语法:@@{…}
有不同类型的网址:
绝对网址---->>>
绝对网址:http://www.thymeleaf.org![]()
相对网址---->>
页面相对:user/login.html
或者是上下文相对:
(将自动添加服务器中的上下文名称)/itemdetails?id=3
相对于服务器:(允许在同一服务器中调用另一个上下文(= 应用程序)中的 URL。~/billing/processInvoiceimport org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; @Controller public class testController { @RequestMapping("/test/{name}") @ResponseBody public String test01( @PathVariable String name) { return name; } }
传入多个参数如果需要多个参数,这些参数将用逗号分隔:@{/order/process(execId=${execId},execType='FAST')} URL 路径中也允许使用变量模板:@{/order/{orderId}/details(orderId=${orderId})}@Controller public class testController { @RequestMapping("/test/{name}/{age}") @ResponseBody public String test01(@PathVariable String name, @PathVariable Integer age) { return name + age; } } //点我呀这些表达式的实际处理及其到将要输出的 URL 的转换由注册到正在使用的对象中的接口的实现完成。org.thymeleaf.linkbuilder.IlinkBuilderITemplateEngine
默认情况下,此接口的单个实现是类的注册,这对于脱机(非Web)和基于Servlet API的Web方案都足够了。其他方案(如与非 ServletAPI Web 框架的集成)可能需要链接生成器界面的特定实现。org.thymeleaf.linkbuilder.StandardlinkBuilder
除了上述方式还可以通过请求发或者响应重定向来实现另一个业务需求;
比如删除商品信息controller层
@RequestMapping("/showall") public ModelAndView showall(Mapmap) { Goods goodsById = goodsService.findGoodsById(1); map.put("goods",goodsById); List goods = goodsService.showGoods(); map.put("goodsInfo", goods); map.put("set",new HashSet<>()); map.put("today", new Date()); int[]i={1,2,3}; map.put("arrayDemo",i); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("sample3"); return modelAndView; } @RequestMapping("/removeInfo") public String removeInfo(Integer id){ int i = goodsService.removeInfo(id); return "redirect:showall"; }
索引 序号 总数 偶数索引 基数索引 第一? 最后? 菜品编号 菜品名称 菜品价格 菜品描述 优惠信息 操作 删除
如果是请求转发,则地址栏上会发生变化
引入css
引入Javascript:
小案例—>>
id, goodsName, price, goodsDesc 后端:----->>>
@RequestMapping("/showA") public ModelAndView showA(Mapmap) { List goods = goodsService.showGoods(); ModelAndView modelAndView = new ModelAndView(); map.put("goodsInfo",goods); modelAndView.setViewName("sample4"); return modelAndView; } @RequestMapping("/removeGoods") public String removeGoods(Integer id,String goodsname){ int i = goodsService.removeInfo(id,goodsname); return "redirect:showA"; } @ResponseBody @RequestMapping("/comments") public String comments(Integer id,String goodsname){ Goods goodsById = goodsService.findGoodsById(id,goodsname); return goodsById.getGoodsname(); } 这里实现了弹窗提醒,主要是运用了th:click方式来触发js函数;
超链接:超链接th:onclick
给元素绑定事件,单击事件并传递参数
写法1:仅仅支持数字和布尔类型参数的传递,字符串不支持删除写法2:支持数字和文本类型的参数传递
删除模板模板的标准存放位置/templates/footer.html
模板 定义和引用片段© 2022 The Good Thymes Virtual Grocery在我们的模板中,我们经常希望包含其他模板中的部分,如页脚,页眉,菜单等部分…
我们想要在某个模板中添加一些别的模板中的或者其资源中的信息,我们会用到
th:insert th:replace th:include案例—我们要在页面底部添加一些公司以及认证的商标信息,如果在每一个页面中添加会比较繁琐,于是可以单独建一个页面来实现对该页面元素的引用
定义片段 :(页面名称footer)© 2022 The Good Thymes Virtual Groceryth:insert插入
那么我们只需要在需要的页面中引入以下内容就可以达到效果等效代码---->>>
页面效果
在这里有一个关键的----->>th:fragment
© 2011 The Good Thymes Virtual Groceryth:fragment 就像一个选择器,
首先定义一个模板
th:fragment="selector"Happy New Year当在别的页面引用的时候格式---->>
"~{templatename::selector}" 或者 "(templatename::selector)"th:insert ="~{被引用的页面名即模板名::片段名}",
当然更简便的是
th:insert="(被引用的页面名::片段名)"
~{::selector}"或插入来自同一模板的片段,匹配 。 如果在显示表达式的模板上找不到,则模板调用(插入) 堆栈将遍历到最初处理的模板(根),直到在某个级别匹配。 "~{this::selector}"selectorselector 这种片段方法的一大优点是, 可以将片段写入浏览器完全可显示的页面中, 具有完整甚至有效的标记结构, 同时仍然保留使Thymeleaf将它们包含到其他模板中的能力。即使不定义 fragment片段,我们也可以完成插入/引用
例如:
footer.html© 2011 The Good Thymes Virtual Grocery
这个就跟元素选择器很像了,通过其属性引用它,类似于CSS选择器:id
除此之外还有----->> th:replace th:include,
th:replace 替换© 2022 The Good Thymes Virtual Grocery1© 2022 The Good Thymes Virtual Grocery2
th:include只插入内容ThymeLeaf2三种的对比
th:insert是最简单的:它只会插入指定的片段作为其主机标记的主体。
th:replace实际上将其主机标记替换为指定的片段。
th:include与 类似,但不是插入片段,而是仅插入此片段的内容。
但是在thymeleaf3.0及以后的版本中不在建议这么食用这三种标签,所以了解即可;
刚刚测试每修改一次就需要重启一些服务,比较繁琐,有一种方式是引入spring开发工具来实现修改之后的自动编译
引入依赖
org.springframework.boot spring-boot-devtools 2.6.3 设置一下idea
设置registry
某些资源在更改时不一定需要触发重新启动。 例如,Thymeleaf 模板可以就地编辑。 默认情况下,更改资源 /meta-INF/maven, /meta-INF/resources, /resources, /static, /public, 或者 /templates不会触发重新启动,但会触发 实时重新加载 。 如果要自定义这些排除项,可以使用 spring.devtools.restart.exclude财产。 例如,仅排除 /static和 /public您将设置以下属性:
特性
yamlspring.devtools.restart.exclude=static/,public/
如果要保留这些默认值并 添加 其他排除项,请使用 spring.devtools.restart.additional-exclude而是财产。片段的参数化
为模板片段创建更像函数的机制,定义的片段可以指定一组参数:th:fragment测试 © 2022 The Good Thymes Virtual Grocery1© 2022 The Good Thymes Virtual Grocery2© 2022 codeM.com别的资源可以引用该资源下的片段内容:
ThymeLeaf1 ThymeLeaf2 ThymeLeaf2 ThymeLeaf2现在已经不推荐这种用法了;所以了解一下即可;
模板引擎对比jsp 优点: 1、功能强大,可以写java代码 2、支持jsp标签(jsp tag) 3、支持表达式语言(el) 4、官方标准,用户群广,丰富的第三方jsp标签库 缺点: 性能问题。不支持前后端分离 freemarker FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。 目前企业中:主要用Freemarker做静态页面或是页面展示 优点: 1、不能编写java代码,可以实现严格的mvc分离 2、性能非常不错 3、对jsp标签支持良好 4、内置大量常用功能,使用非常方便 5、宏定义(类似jsp标签)非常方便 6、使用表达式语言 缺点: 1、不是官方标准 2、用户群体和第三方标签库没有jsp多 Thymeleaf Thymeleaf是个XML/XHTML/HTML5模板引擎,可以用于Web与非Web应用。 Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑。Thymeleaf的可扩展性也非常棒。你可以使用它定义自己的模板属性集合,这样就可以计算自定义表达式并使用自定义逻辑。这意味着Thymeleaf还可以作为模板引擎框架。 优点:静态html嵌入标签属性,浏览器可以直接打开模板文件,便于前后端联调。springboot官方推荐方案。 缺点:模板必须符合xml规范 VUE: 前后端分离,最多,未来趋势Java相关栏目本月热门文章
- 1【Linux驱动开发】设备树详解(二)设备树语法详解
- 2别跟客户扯细节
- 3Springboot+RabbitMQ+ACK机制(生产方确认(全局、局部)、消费方确认)、知识盲区
- 4【Java】对象处理流(ObjectOutputStream和ObjectInputStream)
- 5【分页】常见两种SpringBoot项目中分页技巧
- 6一文带你搞懂OAuth2.0
- 7我要写整个中文互联网界最牛逼的JVM系列教程 | 「JVM与Java体系架构」章节:虚拟机与Java虚拟机介绍
- 8【Spring Cloud】新闻头条微服务项目:FreeMarker模板引擎实现文章静态页面生成
- 9JavaSE - 封装、static成员和内部类
- 10树莓派mjpg-streamer实现监控及拍照功能调试
- 11用c++写一个蓝屏代码
- 12从JDK8源码中看ArrayList和LinkedList的区别
- 13idea 1、报错java: 找不到符号 符号: 变量 log 2、转换成Maven项目
- 14在openwrt使用C语言增加ubus接口(包含C uci操作)
- 15Spring 解决循环依赖
- 16SpringMVC——基于MVC架构的Spring框架
- 17Andy‘s First Dictionary C++ STL set应用
- 18动态内存管理
- 19我的创作纪念日
- 20Docker自定义镜像-Dockerfile
热门相关搜索路由器设置 木托盘 宝塔面板 儿童python教程 心情低落 朋友圈 vim 双一流学科 专升本 我的学校 日记学校 西点培训学校 汽修学校 情书 化妆学校 塔沟武校 异形模板 西南大学排名 最精辟人生短句 6步教你追回被骗的钱 南昌大学排名 清朝十二帝 北京印刷学院排名 北方工业大学排名 北京航空航天大学排名 首都经济贸易大学排名 中国传媒大学排名 首都师范大学排名 中国地质大学(北京)排名 北京信息科技大学排名 中央民族大学排名 北京舞蹈学院排名 北京电影学院排名 中国戏曲学院排名 河北政法职业学院排名 河北经贸大学排名 天津中德应用技术大学排名 天津医学高等专科学校排名 天津美术学院排名 天津音乐学院排名 天津工业大学排名 北京工业大学耿丹学院排名 北京警察学院排名 天津科技大学排名 北京邮电大学(宏福校区)排名 北京网络职业学院排名 北京大学医学部排名 河北科技大学排名 河北地质大学排名 河北体育学院排名




