没有系统学过thymeleaf,只是在做谷粒商城项目的时候用的多了,想着在这儿总结一下。
Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的html文档。从字面上理解模板引擎,最重要的就是模板
二字,这个意思就是做好一个模板后套入对应位置的数据,最终以html的格式展示出来,这就是模板引擎的作用。
模板引擎的功能就类似我们的会议室开会一样开箱即用,将模板设计好之后直接填充数据即可而不需要重新设计整个页面。提高页面、代码的复用性。
动静分离: Thymeleaf选用html
作为模板页,这是任何一款其他模板引擎做不到的!Thymeleaf使用html通过一些特定标签语法代表其含义,但并未破坏html结构
,即使无网络、不通过后端渲染也能在浏览器成功打开,大大方便界面的测试和修改。
开箱即用: Thymeleaf提供标准和Spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、改JSTL、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言。
Springboot官方大力推荐和支持,Springboot官方做了很多默认配置,开发者只需编写对应html即可,大大减轻了上手难度和配置复杂度。
Thymeleaf在曾经还有一次大的版本升级,从Thymeleaf2.0—>Thymeleaf3.0。在Thymeleaf2.0时代,Thymeleaf基于xml实现,虽然它带来了许多出色强大的功能,但有时会降低性能效率,那个时候Thymeleaf的性能真的太差而被很多人所吐槽带来了很不好的印象。
但是Thymeleaf3.0对比Thymeleaf2.0有着翻天覆地的变化,几乎是全部重写了整个Thymeleaf引擎,在性能、效率上相比Thymeleaf2有了很大改善,能够满足更多项目的需求,且Thymeleaf3.0不再基于xml所以在html环境下有着更宽松的编程环境。
你可能还是不明白什么才是真正的动静分离,其实这个主要是由于Thymeleaf模板基于html,后缀也是.html
,所以这样就会产生一些有趣的灵魂。
对于传统jsp或者其他模板来说,没有一个模板引擎的后缀为.html,就拿jsp来说jsp的后缀为.jsp
,它的本质就是将一个html文件修改后缀为.jsp,然后在这个文件中增加自己的语法、标签然后执行时候通过后台处理这个文件最终返回
一个html页面。
浏览器无法直接识别.jsp文件,需要借助网络(服务端)
才能进行访问;而Thymeleaf用html做模板可以直接在浏览器中打开。开发者充分考虑html页面特性,将Thymeleaf的语法通过html的标签属性来定义完成,这些标签属性不会影响html页面的完整性和显示。如果通过后台服务端访问页面服务端会寻找这些标签将服务端对应的数据替换到响应位置实现动态页面!大体区别可以参照下图:
上图的意思就是如果直接打开这个html那么浏览器会对th等标签忽视而显示原始的内容。如果通过服务端访问那么服务端将先寻找th标签将服务端储存的数据替换到对应位置。具体效果可以参照下图,下图即为一个动静结合的实例。
动态页面每次修改打开都需要重新启动程序、输入链接,这个过程其实是相对漫长的。如果界面设计人员用这种方式进行页面设计时间成本高并且很麻烦,可通过静态页面设计样式,设计完成通过服务端访问即可达成目标UI的界面和应用,达到动静分离的效果。这个特点和优势是所有模板引擎中Thymeleaf所独有的
4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.5 com.example.lx demo 0.0.1-SNAPSHOT demo Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools true org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin
package com.example.lx.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;@Controller
public class IndexController {@GetMapping("/index")public String index(Model model){model.addAttribute("message","thymeleaf");// 默认前缀和后缀是 classpath:/templates/和.html// 所以这儿写个index就可以跳转到页面了return "index";}
}
index
// 是否允许页面缓存的配置,我们在开发时候要确保页面是最新的所以需要禁用缓存;
// 而在上线运营时可能页面不常改动为了减少服务端压力以及提升客户端响应速度会允许页面缓存的使用
spring.thymeleaf.cache=false
上面我们已经学习到Thymeleaf是一个基于html的模板引擎,但是我们还是需要加入特定标签来声明和使用Thymeleaf的语法。我们需要在Thymeleaf的头部加Thymeleaf标识(名称空间):
在Thymeleaf 中,如果想引入链接比如link,href,src,需要使用@{资源地址}引入资源。其中资源地址可以static目录下的静态资源,也可以是互联网中的绝对资源。
超链接
这样启动程序访问页面,页面的内容就自动修改成标准html语法格式的内容:
// templates目录下建立home.properties
bigsai.nane=bigsai
bigsai.age=22
province=Jiang Su// application.properties
spring.messages.basename=templates/home//html
搜索
'javascript:searchProducts("catalog3Id",' + catalog.catalogId + ')'}"
th:text="${catalog.catalogName}"> function searchByKeyWord(){searchProducts("keyword",$('#keyword_input').val())}
:
×
(#strings.isEmpty(p) || #strings.startsWith(p,'hotScore'))?'border-color: #e4393c;color:#FFF;background: #e4393c':'border-color: #CCC;color:#333;background: #fff'}"th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"sort="hotScore" href="#">综合排序[[${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]
(#strings.isEmpty(p)
|| #strings.startsWith(p,'hotScore'))?
'border-color: #e4393c;color:#FFF;background: #e4393c':'border-color: #CCC;color:#333;background: #fff'}"th:attr="pn=${result.pageNum - 1}"
// 判断是否为空
#strings.isEmpty()// 判断a是否以b开头
#strings.startsWith(a,b)
#strings.endsWith()// 截取priceRange中 _ 之后的值
#strings.substringAfter(priceRange,'_')
#strings.substringBefore(priceRange,'_')// 判断列表中是否有该值
#lists.contains(result.attrIds,attr.attrId)// 数字格式化
// param1 要格式化的数字
// param2 整数位数,如果写的少了,也不会抹去
// param3 小数位数
#numbers.formatDecimal(a,b,c)// 以b分割a,return String[]
#strings.arraySplit(a,b)
" 双引号
例如:th:if和th:with在同一标签内,th:with定义一个变量,th:if使用这个变量,因为优先级的关系,th:if先使用,th:with后定义,这样就出现了错误。
// 在上面的优先级高
th:ifth:with
(#strings.isEmpty(p) || #strings.startsWith(p,'hotScore'))?'border-color: #e4393c;color:#FFF;background: #e4393c':'border-color: #CCC;color:#333;background: #fff'}"
th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"
sort="hotScore" href="#">综合排序[[${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]
thymeleaf从控制器类向前端页面跳转时,指定传递的页面
返回的就是我要显示的页面名
当返回的就是我要显示的页面名时,使用thymeleaf解析器(thymeleaf设置的视图解析器)解析出文件地址,转发方式跳转到该页面,具体代码见入门程序。
forward 请求转发
当以forward为前缀时,创建internalsersourceview
视图,此时不会直接被thymeleaf解析,而是将forward去掉,寻找控制器的value一样的方法,用thymeleaf解析该方法的返回值,并请求转发
访问该页面
// 会寻找有 @RequestMapping("/test_thymeleaf")的控制方法,
// 用thymeleaf解析该方法的返回值,得出文件的路径,并请求转发跳转至该页面
@RequestMapping("/forward_thymeleaf")public String forwrad_thyleaf(){return "forward:/test_thymeleaf";}
redirect
当以redirect为前缀时,创建internalsersourceview视图,此时不会直接被thymeleaf解析,而是将redirect去掉,寻找控制器的value一样的方法,用thymeleaf解析该方法的返回值,并重定向
访问该页面
// 会寻找有 @RequestMapping("/test_thymeleaf")的控制方法,
// 用thymeleaf解析该方法的返回值,得出文件的路径,并请求重定向至该页面
@RequestMapping("/forward_thymeleaf")public String forwrad_thyleaf(){return "redirect:/test_thymeleaf";}
使用model modelandview
// forward和redirect是不管返回值是model modelandview 都可以使用
@RequestMapping(value = "/update2")
public ModelAndView after_choose_change(Books books)
{booksServiceimpl.updateBook(books);System.out.println("books 这是修改后的books"+books);ModelAndView modelAndView=new ModelAndView();modelAndView.setViewName("redirect:/books/allbooks");return modelAndView;
}
不需要传递数据的跳转
package com.atlinxi.gulimall.authserver.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 发送一个请求直接跳转到一个页面,我们又不想controller中写这些空方法* SpringMvc viewcontroller:将请求和页面映射过来* @return*/
@Configuration
public class GulimallWebConfig implements WebMvcConfigurer {/*** 直接跳转(渲染一个页面),无需写自定义的controller*** @param registry*/@Overridepublic void addViewControllers(ViewControllerRegistry registry) {/*** * @GetMapping("/login.html")* * public String loginPage(){* ** * return "login";* * }*/registry.addViewController("/login.html").setViewName("login");registry.addViewController("/reg.html").setViewName("reg");}
}
不能使用ajax请求进行页面跳转
在做谷粒商城注册页面的时候,用到了通过cotroller进行页面跳转,我也忘了是为什么,可能只是想试一试,在html页面中写一个点击事件,请求controller进行页面跳转,非常简单,结果实在是出乎意料。
页面没有任何变化,请求进入controller,浏览器控制台打印返回结果,它把整个html以文本的方式打印出来了。。。。。。。
最后还是靠百度,ajax 只能实现局部刷新,无法执行整体的页面跳转并携带数据
,使用重定向也无法跳转到其他的页面。
解决:
- 把 Ajax 请求改成了 form 表单
- location.href
部分内容转载自:
https://zhuanlan.zhihu.com/p/163391278(写的超级好)
https://blog.csdn.net/sharesb/article/details/124381312
https://blog.csdn.net/weixin_45784666/article/details/121450116
相关内容