Thymeleaf是SpringBoot默认的模板引擎,但是这个模板引擎使用上有一些坑,本文主要对Thymeleaf的坑做一下总结记录。
坑一:Html/JS代码转义问题
正经篇:
Thymeleaf对Html、JS代码要求极其严格,稍微不注意,就会报错。(严格到没有天理。。。。。)
HTML
由于历史问题,Html的代码一直以来都不规范,即使有了规范,Html解析器也会对Html代码保持“宽容”,对不规范的代码照样处理。如:Html有些标签已经限定了必须加上/表示结束,而有些便签则可能不加,如<link>、<meta>、<img>等。
而Thymeleaf 则对Html代码要求特别严格,一些稍微没有闭合的标签就会报异常无法解析。
解决方案(减少Thymeleaf对Html规范要求):
在SpringBoot下,只需添加依赖:
<dependency> <groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId> <version>1.9.21</version> </dependency>
再在配置文件中配置
spring: thymeleaf: suffix: .html prefix: classpath:/templates/ mode:
LEGACYHTML5
就可以完美解决Thymeleaf对Html代码及JS代码转义的问题。
JS
Thymeleaf会对Html文件中的js代码当成Html代码进行解析,然后就会出现吊轨的一幕。<、>、&等都报错。一系类奇奇怪怪的问题。
解决方案:在 js 里加上 /*<![CDATA[*/ 和 /*]]>*/
,避免转义。【当然,如果添加了nekohtml依赖处理,则不会对这些符号进行还转义,就不会出现这个问题】
故事搞笑篇:
1.对Html代码严格限制
标签们经常会到各大Html解析器的家里玩。一些标签们不喜欢上门带礼物(带上闭合标签),解析器们对其处理一般是睁一只眼闭一只眼,因为这几年对收礼行为处理得很严重。而Thymeleaf就不一样了,就要搞特殊,就要收礼,没带礼物的话,嘿嘿。
故事就这样展开了。。。。。
<link>、<img>、<input>标签们:来呀,老弟们,我们一起组队去串门,说好了大家都不许带礼,“法不责众”。
Html解析器(浏览器等)
:可爱的标签们来啦。哈哈哈,有没有带。。。。额。行吧,我睁一只眼闭一只眼,谁叫最近查的严呢,不规范就不规范了,我来解决你代码不规范的问题,不规范我会兼容,让你们这些标签尽可能显示。.
(生活就要佛系,不送礼不打紧,事情照样办的杠杠的)
<link>标签
:这个浏览器那么好,在他家他帮我们办事还请我们吃了饭。好久没吃那么饱了,下次我们去下一家吃饭,抽个签去哪里好了。。(抽到|Thymeleaf)。
<img>标签:这是啥?。。
<meta> 标签(发抖):这。。。他就住在我们隔壁。。。这是一个啥礼都收的家伙。恐怕去了我们不能两手空空去呀。。
<link>标签:甭管啥,崩怕,我们明天一起去,万物皆可盘,我们还怕它?明天大家还是老样子,让它长点见识,我们可不是盖的。
第二天。。。。。。。
<link>、<img>、<input>标签们(敲门):老王。我们来蹭饭了。你不出来,我们就一个一个进去咯。
Thymelea(小名叫老王)
:(又有人来送礼了,其实我也不是很想收,他们不好意思叫我做事(解析),就给我礼物,我也不好拒绝呀。但是,如果这些标签敢不按“标准行事”我就让他们吃不了兜着走。敢不送礼叫我做事?找shi!!!!)
好的,我画好装了,怕羞,你们一个个进来吧。你们懂得的。
于是,在这些标签们去Thymeleaf家里玩不带上礼物,就会
<link> : 我来啦老王,你家里有什么好吃的吗?我要....
thymeleaf:first blood(一血)
org.xml.sax.SAXParseException: The element type "link" must be terminated by
the matching end-tag "</link>". at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown
Source) ~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na]
<meta> : 我来啦老王,你家里有什么好吃的....
thymeleaf:doublekill(双杀)
org.xml.sax.SAXParseException: The element type "meta" must be terminated by
the matching end-tag "</meta>". at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown
Source) ~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown
Source) ~[xercesImpl-2.10.0.jar:na]
<img> : 我来啦老王,你家里....
thymeleaf: triplekill(三杀)
org.xml.sax.SAXParseException: The element type "img" must be terminated by
the matching end-tag "</img>". at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown
Source) ~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown
Source) ~[xercesImpl-2.10.0.jar:na]
<input> : 我来啦老王....
thymeleaf:quatarykill(四杀)
org.xml.sax.SAXParseException: The element type "input" must be terminated by
the matching end-tag "</input>". at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown
Source) ~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEndElement(Unknown
Source) ~[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown
Source) ~[xercesImpl-2.10.0.jar:na]
<br> : 我....只是路过的。。。。
thymeleaf:pentakill(五杀)
org.xml.sax.SAXParseException: The element type "br" must be terminated by the
matching end-tag "</br>". at
org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown
Source) [xercesImpl-2.10.0.jar:na] at
org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
[xercesImpl-2.10.0.jar:na] at
org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
[xercesImpl-2.10.0.jar:na]
thymeleaf:beyond godlike(神一样)
2.对JS代码限制
Thymeleaf对JS也有限制,会对js中的代码进行转义。此刻就会出错了。
听完一群标签们被揍的事情后,JS不以为然,毕竟家里有矿。
JS在一旁乐呵呵:我就没事,看我去找老王。
JS:老王呀,我可是不用带礼物的,因为我爸是李。。。
Thymeleaf:Seven-hour close to
JS的爸李某:我可是有牌面的,居然被这个小子羞辱我儿,看我的。
解决方案:在 js 里加上 /*<![CDATA[*/ 和 /*]]>*/ ,避免转义。
JS:来呀,大凶带,我说了吧,我爸是李gang。
Thymeleaf:真的呀,误会误会,改天我请客表示歉意。。真误会,不好意思。
3.解决方案:程序员小哥(标签们的大老板):
程序小哥:这Thymeleaf真的是太不像话了,再这样下去我可要破产了。不行,我要去网上找找有没有破解版的。
于是,解决方案来了。
在SpringBoot下,只需要添加依赖
<dependency> <groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId> <version>1.9.21</version> </dependency>
再在配置文件中配置
spring: thymeleaf: suffix: .html prefix: classpath:/templates/ mode:
LEGACYHTML5
就可以使用“盗版”,这次小哥终于可以不用花钱送礼了。开森。
坑二:th:fragment引用问题(20190223更新)
Thymeleaf的模块化是通过th:fragment属性等完成的。
普通的使用当然不会出现问题,但是,如果“特殊”地使用就会发生灵异事件了。。。。。
一般在写好th:fragment代码后,需要在“包含它”的地方使用div的th:include标签进行引入。
<div th:include="/common/header::Header"/>
以上方式有时候会出现问题的。
返回的Html代码可能仅仅包含Header里面的代码(具体看你包含这个头的代码如何include)。
大白话讲就是,在<div th:include="/common/header::Header"/> 之后的Html代码,无法显示。被截断了。
发生场景:
1.为了解除Thymeleaf对Html代码的严格要求,
在SpringBoot下,添加了依赖
<dependency> <groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId> <version>1.9.21</version> </dependency>
2.然后th:fragment代码通过div的th:include标签进行引入。而此时标签是直接闭合的。
<div th:include="/common/header::Header"/>
结果,Html代码就被截断了。这是添加nekohtml后,<div th:include>标签直接闭合导致的结果。
解决方案:
很简单。这样就好了。。。Thymeleaf的“坑”不少鸭
<div th:include="/common/header::Header"> </div>
坑三:待发现(待更新)
欲加之罪,何患无辞。嘿嘿嘿
热门工具 换一换