程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

SpringBoot系列之集成Thymeleaf用法手册

发布于2021-06-12 14:45     阅读(697)     评论(0)     点赞(4)     收藏(5)


1、模板引擎

引用百度百科的模板引擎解释:

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

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

2、Thymeleaf简介

2.1)、Thymeleaf定义

Thymeleaf是适用于Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。具体参考Thymeleaf官网

官网提供了在线文档也有文件格式的各种文档
在这里插入图片描述

2.2)、适用模板

Thymeleaf适用于如下模板:

  • HTML
  • XML
  • TEXT
  • JAVASCRIPT
  • CSS
  • RAW

有两种标记模板模式(HTML 和 XML)、三种文本模板模式(TEXT、JAVASCRIPT 和 CSS)和一种无操作模板模式 (RAW)。

ok,下面给出一些比较重要的知识点

3、重要知识点

3.1)、th:text和th:utext

这是很常用的text标签,作用是Thymeleaf中设置文本的标签,分为两种,一种是th:text,另外一种是th:utext,两种最重要的区别就是会不会对特殊字符进行转义

  • th:text:将所有特殊字符转成字符
  • th:utext:不会将特殊字符进行字符转义

注意:这里的特殊字符主要指html标签,/n、/t、etc.这些字符是不支持的
写个例子对比一下:


  
  1. <span th:text="${'Welcome to our <b>fantastic</b> grocery store!'}"> </span> <br/>
  2. <span th:utext="${'Welcome to our <b>fantastic</b> grocery store!'}"> </span>

在这里插入图片描述

3.2)、标准表达式

官方文档里有standard Expression Syntax这个章节,介绍的就是标准的表达式语法应用

  • Simple expressions(简单表达式语法):
    • Variable Expressions: ${...} // 获取遍历值,支持OGNL语法 etc.
    1. 获取自定义对象的属性值
    2. 获取自定义的变量属性值
    3. 使用内置的基本对象
      • ctx: the context object.

      • vars: the context variables.

      • locale: the context locale.

      • request: (only in Web Contexts) the HttpServletRequest object.

      • response: (only in Web Contexts) the HttpServletResponse object.

      • session: (only in Web Contexts) the HttpSession object.

      • servletContext: (only in Web Contexts) the ServletContext object.

      详情参考Thymeleaf的附录A
    4. 内置的工具类对象
      官网已经给出比较详细的介绍,详细用法参考Thymeleaf附录B
      在这里插入图片描述
    • Selection Variable Expressions: *{...} // 选定对象,也就是获取使用 th:object 属性的表达式的值
    • Message Expressions: #{...} //国际化内容 详细用法参考我的博客:SpringBoot系列之i18n国际化多语言支持教程
    • Link URL Expressions: @{...} // 定义URL链接

  
  1. <link th:href="@{/static/css/public.css}" rel="stylesheet" type="text/css" />
  2. <link th:href="@{/static/css/index.css}" rel="stylesheet" type="text/css" />
  3. <script type="text/javascript" th:src="@{/static/js/jquery-1.3.2.min.js}"> </script>
  4. <script type="text/javascript" th:src="@{/static/js/html5.js}"> </script>
  5. <script type="text/javascript" th:src="@{/static/js/popbox.js}"> </script>
* Fragment Expressions: ~{...} //片段引用的表达式 eg: `<div th:insert="~{commons :: main}">....</div>`
  
  • 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: + //连接操作 @{url/}+${id}
    • Literal substitutions: |The name is ${name}| //字符串中使用${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:(条件运算,包括三元运算符etc.)
    • If-then: (if) ? (then)
    • If-then-else: (if) ? (then) : (else)
    • Default: (value) ?: (defaultvalue)
  • Special tokens:(特殊的令牌,也就是使用No-Operatio)
    • No-Operation: _
      在这里插入图片描述

      All these features can be combined and neste:
      'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))

翻译过来意思是,这些语法都可以组合使用,这个章节是Thymeleaf一个重要的基本使用章节,本博客对一些重要的知识点进行摘录同时介绍一下在SpringBoot里如何使用,当然自然没有官方文档详细的,不过官方并没有通过中文文档,英文水平不好的话,阅读起来比较困难,当然我也找了一篇国内翻译过来的Thymeleaf中文文档,读者详细的可以参考文档

3.3)、Thymeleaf遍历

遍历是Thymeleaf很常用的例子,支持的属性值有:
在这里插入图片描述
下面还是给下例子,比较容易理解,如下代码使用th:each,th:each="item : ${items}"


  
  1. <!--最新上架-->
  2. <div class="first-pannel clearfix">
  3. <div class="index-f clearfix">
  4. <h3 class="index-f-head"> 最新上架 <span>每天都有上新,每天都有惊喜 </span> </h3>
  5. <div class="index-f-body">
  6. <div class="top-sales newProduct">
  7. <ul class="top-sales-list clearfix">
  8. <li class="top-sales-item newProduct" th:each="item : ${items}">
  9. <p class="item-img"> <a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}"> <img th:src="@{${item.imgPath}}" /> </a> </p>
  10. <p class="item-buss"> <a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}"> </a> </p>
  11. <p class="item-name spec"> <a th:href="@{'/portal/item/toDetail/'+${item.spuId}+'/'+${item.skuId}}" th:text="${item.itemName}"> </a> </p>
  12. <p class="item-price spec"> <em th:text="${item.mPrice}"> </em></p>
  13. </li>
  14. </ul>
  15. </div>
  16. </div>
  17. </div>
  18. </div>
  19. <!--最新上架//-->

3.4)、公共模块抽取

在项目开发中经常遇到一些可以重用的页面,这时候就可以Thymeleaf的Template Layout进行公共页面的复用

本博客以官方介绍的复用footer.html页面进行说明
在这里插入图片描述
使用步骤:

  1. 抽取公共的片段

  
  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <body>
  4. <div th:fragment="copy">
  5. &copy; 2011 The Good Thymes Virtual Grocery
  6. </div>
  7. </body>
  8. </html>
  1. 引入公共的片段
    <div th:insert="~{footer :: copy}"></div>
    ~{templatename::selector}:模板名::选择器
    ~{templatename::fragmentname}:模板名::片段名

  
  1. <div th:insert="footer :: copy"> </div>
  2. <div th:replace="footer :: copy"> </div>
  3. <div th:include="footer :: copy"> </div

三种引入公共片段的th属性:

  • th:insert:将公共片段整个插入到声明引入的元素中
  • th:replace:将声明引入的元素替换为公共片段
  • th:include:将被引入的片段的内容包含进这个标签中

效果对比:


  
  1. <div>
  2. <footer>
  3. &copy; 2011 The Good Thymes Virtual Grocery
  4. </footer>
  5. </div>
  6. <footer>
  7. &copy; 2011 The Good Thymes Virtual Grocery
  8. </footer>
  9. <div>
  10. &copy; 2011 The Good Thymes Virtual Grocery
  11. </div

3.5)、行内写法介绍

所谓行内写法就是没写在html对应的标签里的写法,直接在页面空白处,用[[....]]或者[(....)]的写法,然后[[....]]和[(....)]的区别其实就等同于th:text和th:utext的区别,一个会进行转义,一个不会转义特殊字符

  • [[....]]写法:会转义html标签这些特殊字符(转成字符)
  • [(....)]写法:不会转义html标签这些特殊字符(按照其原意)
    写个例子就明白了:
    在这里插入图片描述

  
  1. <span>
  2. The message is [[${msg}]]
  3. </span>
  4. <br/>
  5. <span>
  6. The message is [(${msg})]
  7. </span>

在这里插入图片描述

3.6)、Thymeleaf语法规则

引用尚桂谷老师的归纳:
在这里插入图片描述

4、SpringBoot集成

4.1)、Springboot集成Thymeleaf简介

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


  
  1. <!-- Themeleaf -->
  2. <dependency>
  3. <groupId>org.springframework.boot </groupId>
  4. <artifactId>spring-boot-starter-thymeleaf </artifactId>
  5. </dependency>

application.yml配置
注意:这里的属性大部分都可以不配置的,因为Springboot的自动配置因为做了很多自动配置,我们不配置,就使用默认的,不过下面的例子只是给读者了解一下有这些配置


  
  1. #添加Thymeleaf配置,除了cache在项目没上线前建议关了,其它配置都可以不用配的,本博客只是列举一下有这些配置
  2. thymeleaf:
  3. # cache默认开启的,这里可以关了,项目上线之前,项目上线后可以开启
  4. cache: false
  5. # 这个prefix可以注释,因为默认就是templates的,您可以改成其它的自定义路径
  6. prefix: classpath:/templates/
  7. suffix: .html
  8. mode: HTML5
  9. # 指定一下编码为utf8
  10. encoding: UTF-8
  11. # context-type为text/html,也可以不指定,因为boot可以自动识别
  12. content-type: text/html

ok,Springboot中Thymeleaf使用非常简单,因为Springboot已经为我们做了很多自动配置,其实,yaml都不需要配置的,直接引入对应的jar,然后就可以直接使用,在resources资源文件夹下面新建一个templates文件夹,所有的html文件都丢在这里,静态资源文件也丢在resources资源文件夹下面

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

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


  
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title </title>
  6. </head>
  7. <body>
  8. <div>
  9. <span th:text="${'Welcome to our <b>fantastic</b> grocery store!'}"> </span> <br/>
  10. <span th:utext="${'Welcome to our <b>fantastic</b> grocery store!'}"> </span>
  11. </div>
  12. <span>
  13. The message is [[${msg}]]
  14. </span>
  15. <br/>
  16. <span>
  17. The message is [(${msg})]
  18. </span>
  19. </body>
  20. </html>

4.2)、Thymeleaf自动配置源码简单分析

ok,然后为什么我说直接引入对应pom配置就可以直接使用了?因为Springboot已经为项目做了很多自动配置,所以本博客简单跟一下源码,了解一下SpringbootThymeleaf的自动配置

SpringBoot的自动配置类在ThymeleafAutoConfiguration里


  
  1. package org.springframework.boot.autoconfigure.thymeleaf;
  2. ....
  3. @Configuration(proxyBeanMethods = false) //定义这是一个配置类
  4. @EnableConfigurationProperties(ThymeleafProperties.class) //使用ThymeleafProperties属性类的属性
  5. @ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class }) //指定TemplateMode、SpringTemplateEngine(模板引擎类)起效的情况,整个配置类才起作用
  6. @AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class }) //必须在WebMvcAutoConfiguration(SpringMVC自动配置类,这个配置类会加载组装所有的视图解析器)、WebFluxAutoConfiguration类起效后,这个Thymeleaf自动配置类才起效
  7. public class ThymeleafAutoConfiguration {
  8. //没有自定义的模板解析器类的情况,使用默认的模板解析器
  9. @Configuration(proxyBeanMethods = false)
  10. @ConditionalOnMissingBean(name = "defaultTemplateResolver")
  11. static class DefaultTemplateResolverConfiguration {
  12. private static final Log logger = LogFactory.getLog(DefaultTemplateResolverConfiguration.class);
  13. //Thymeleaf的properties配置
  14. private final ThymeleafProperties properties;
  15. private final ApplicationContext applicationContext;
  16. DefaultTemplateResolverConfiguration(ThymeleafProperties properties, ApplicationContext applicationContext) {
  17. this.properties = properties;
  18. this.applicationContext = applicationContext;
  19. }
  20. //用PostConstruct注解,在依赖注入完成之后,实现类的初始化配置,这个方法主要是检查模板引擎的资源文件路径是否有
  21. @PostConstruct
  22. void checkTemplateLocationExists() {
  23. boolean checkTemplateLocation = this.properties.isCheckTemplateLocation();
  24. if (checkTemplateLocation) {
  25. TemplateLocation location = new TemplateLocation( this.properties.getPrefix());
  26. if (!location.exists( this.applicationContext)) {
  27. logger.warn( "Cannot find template location: " + location + " (please add some templates or check "
  28. + "your Thymeleaf configuration)");
  29. }
  30. }
  31. }
  32. //默认的Thymeleaf资源解析器
  33. @Bean
  34. SpringResourceTemplateResolver defaultTemplateResolver() {
  35. SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
  36. //资源解析器的所有配置
  37. resolver.setApplicationContext( this.applicationContext);
  38. resolver.setPrefix( this.properties.getPrefix());
  39. resolver.setSuffix( this.properties.getSuffix());
  40. resolver.setTemplateMode( this.properties.getMode());
  41. if ( this.properties.getEncoding() != null) {
  42. resolver.setCharacterEncoding( this.properties.getEncoding().name());
  43. }
  44. resolver.setCacheable( this.properties.isCache());
  45. Integer order = this.properties.getTemplateResolverOrder();
  46. if (order != null) {
  47. resolver.setOrder(order);
  48. }
  49. resolver.setCheckExistence( this.properties.isCheckTemplate());
  50. return resolver;
  51. }
  52. }
  53. //又是Thymeleaf的自动配置,自动配置模板引擎SpringTemplateEngine
  54. @Configuration(proxyBeanMethods = false)
  55. protected static class ThymeleafDefaultConfiguration {
  56. @Bean
  57. @ConditionalOnMissingBean(ISpringTemplateEngine.class)
  58. SpringTemplateEngine templateEngine(ThymeleafProperties properties,
  59. ObjectProvider<ITemplateResolver> templateResolvers, ObjectProvider<IDialect> dialects) {
  60. SpringTemplateEngine engine = new SpringTemplateEngine();
  61. engine.setEnableSpringELCompiler(properties.isEnableSpringElCompiler());
  62. engine.setRenderHiddenMarkersBeforeCheckboxes(properties.isRenderHiddenMarkersBeforeCheckboxes());
  63. templateResolvers.orderedStream().forEach(engine::addTemplateResolver);
  64. dialects.orderedStream().forEach(engine::addDialect);
  65. return engine;
  66. }
  67. }
  68. @Configuration(proxyBeanMethods = false)
  69. @ConditionalOnWebApplication(type = Type.SERVLET)
  70. @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
  71. static class ThymeleafWebMvcConfiguration {
  72. @Bean
  73. @ConditionalOnEnabledResourceChain
  74. @ConditionalOnMissingFilterBean(ResourceUrlEncodingFilter.class)
  75. FilterRegistrationBean<ResourceUrlEncodingFilter> resourceUrlEncodingFilter() {
  76. FilterRegistrationBean<ResourceUrlEncodingFilter> registration = new FilterRegistrationBean<>(
  77. new ResourceUrlEncodingFilter());
  78. registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ERROR);
  79. return registration;
  80. }
  81. //比较重要的视图解析器配置
  82. @Configuration(proxyBeanMethods = false)
  83. static class ThymeleafViewResolverConfiguration {
  84. @Bean
  85. @ConditionalOnMissingBean(name = "thymeleafViewResolver")
  86. ThymeleafViewResolver thymeleafViewResolver(ThymeleafProperties properties,
  87. SpringTemplateEngine templateEngine) {
  88. ThymeleafViewResolver resolver = new ThymeleafViewResolver();
  89. //设置模板引擎
  90. resolver.setTemplateEngine(templateEngine);
  91. //字符编码设置
  92. resolver.setCharacterEncoding(properties.getEncoding().name());
  93. resolver.setContentType(
  94. appendCharset(properties.getServlet().getContentType(), resolver.getCharacterEncoding()));
  95. resolver.setProducePartialOutputWhileProcessing(
  96. properties.getServlet().isProducePartialOutputWhileProcessing());
  97. resolver.setExcludedViewNames(properties.getExcludedViewNames());
  98. resolver.setViewNames(properties.getViewNames());
  99. // This resolver acts as a fallback resolver (e.g. like a
  100. // InternalResourceViewResolver) so it needs to have low precedence
  101. resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
  102. //Thymeleaf缓存
  103. resolver.setCache(properties.isCache());
  104. return resolver;
  105. }
  106. private String appendCharset(MimeType type, String charset) {
  107. if (type.getCharset() != null) {
  108. return type.toString();
  109. }
  110. LinkedHashMap<String, String> parameters = new LinkedHashMap<>();
  111. parameters.put( "charset", charset);
  112. parameters.putAll(type.getParameters());
  113. return new MimeType(type, parameters).toString();
  114. }
  115. }
  116. }
  117. @Configuration(proxyBeanMethods = false)
  118. @ConditionalOnWebApplication(type = Type.REACTIVE)
  119. @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
  120. static class ThymeleafReactiveConfiguration {
  121. @Bean
  122. @ConditionalOnMissingBean(ISpringWebFluxTemplateEngine.class)
  123. SpringWebFluxTemplateEngine templateEngine(ThymeleafProperties properties,
  124. ObjectProvider<ITemplateResolver> templateResolvers, ObjectProvider<IDialect> dialects) {
  125. SpringWebFluxTemplateEngine engine = new SpringWebFluxTemplateEngine();
  126. engine.setEnableSpringELCompiler(properties.isEnableSpringElCompiler());
  127. engine.setRenderHiddenMarkersBeforeCheckboxes(properties.isRenderHiddenMarkersBeforeCheckboxes());
  128. templateResolvers.orderedStream().forEach(engine::addTemplateResolver);
  129. dialects.orderedStream().forEach(engine::addDialect);
  130. return engine;
  131. }
  132. }
  133. //ThymeleafWebFluxConfiguration自动配置
  134. @Configuration(proxyBeanMethods = false)
  135. @ConditionalOnWebApplication(type = Type.REACTIVE)
  136. @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true)
  137. static class ThymeleafWebFluxConfiguration {
  138. @Bean
  139. @ConditionalOnMissingBean(name = "thymeleafReactiveViewResolver")
  140. ThymeleafReactiveViewResolver thymeleafViewResolver(ISpringWebFluxTemplateEngine templateEngine,
  141. ThymeleafProperties properties) {
  142. ThymeleafReactiveViewResolver resolver = new ThymeleafReactiveViewResolver();
  143. resolver.setTemplateEngine(templateEngine);
  144. mapProperties(properties, resolver);
  145. mapReactiveProperties(properties.getReactive(), resolver);
  146. // This resolver acts as a fallback resolver (e.g. like a
  147. // InternalResourceViewResolver) so it needs to have low precedence
  148. resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
  149. return resolver;
  150. }
  151. private void mapProperties(ThymeleafProperties properties, ThymeleafReactiveViewResolver resolver) {
  152. PropertyMapper map = PropertyMapper.get();
  153. map.from(properties::getEncoding).to(resolver::setDefaultCharset);
  154. resolver.setExcludedViewNames(properties.getExcludedViewNames());
  155. resolver.setViewNames(properties.getViewNames());
  156. }
  157. private void mapReactiveProperties(Reactive properties, ThymeleafReactiveViewResolver resolver) {
  158. PropertyMapper map = PropertyMapper.get();
  159. map.from(properties::getMediaTypes).whenNonNull().to(resolver::setSupportedMediaTypes);
  160. map.from(properties::getMaxChunkSize).asInt(DataSize::toBytes).when((size) -> size > 0)
  161. .to(resolver::setResponseMaxChunkSizeBytes);
  162. map.from(properties::getFullModeViewNames).to(resolver::setFullModeViewNames);
  163. map.from(properties::getChunkedModeViewNames).to(resolver::setChunkedModeViewNames);
  164. }
  165. }
  166. @Configuration(proxyBeanMethods = false)
  167. @ConditionalOnClass(LayoutDialect.class)
  168. static class ThymeleafWebLayoutConfiguration {
  169. @Bean
  170. @ConditionalOnMissingBean
  171. LayoutDialect layoutDialect() {
  172. return new LayoutDialect();
  173. }
  174. }
  175. @Configuration(proxyBeanMethods = false)
  176. @ConditionalOnClass(DataAttributeDialect.class)
  177. static class DataAttributeDialectConfiguration {
  178. @Bean
  179. @ConditionalOnMissingBean
  180. DataAttributeDialect dialect() {
  181. return new DataAttributeDialect();
  182. }
  183. }
  184. @Configuration(proxyBeanMethods = false)
  185. @ConditionalOnClass({ SpringSecurityDialect.class })
  186. static class ThymeleafSecurityDialectConfiguration {
  187. @Bean
  188. @ConditionalOnMissingBean
  189. SpringSecurityDialect securityDialect() {
  190. return new SpringSecurityDialect();
  191. }
  192. }
  193. @Configuration(proxyBeanMethods = false)
  194. @ConditionalOnClass(Java8TimeDialect.class)
  195. static class ThymeleafJava8TimeDialect {
  196. @Bean
  197. @ConditionalOnMissingBean
  198. Java8TimeDialect java8TimeDialect() {
  199. return new Java8TimeDialect();
  200. }
  201. }
  202. }

ThymeleafProperties是SpringBoot的属性配置类,使用ConfigurationProperties注解进行属性映射


  
  1. @ConfigurationProperties(prefix = "spring.thymeleaf")
  2. public class ThymeleafProperties {
  3. private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
  4. //默认的模板资源路径
  5. public static final String DEFAULT_PREFIX = "classpath:/templates/";
  6. //默认解析html资源
  7. public static final String DEFAULT_SUFFIX = ".html";
  8. /**
  9. * Whether to check that the template exists before rendering it.
  10. */
  11. private boolean checkTemplate = true;
  12. /**
  13. * Whether to check that the templates location exists.
  14. */
  15. private boolean checkTemplateLocation = true;
  16. /**
  17. * Prefix that gets prepended to view names when building a URL.
  18. */
  19. private String prefix = DEFAULT_PREFIX;
  20. /**
  21. * Suffix that gets appended to view names when building a URL.
  22. */
  23. private String suffix = DEFAULT_SUFFIX;
  24. /**
  25. * Template mode to be applied to templates. See also Thymeleaf's TemplateMode enum.
  26. */
  27. //默认模式也是html的
  28. private String mode = "HTML";
  29. /**
  30. * Template files encoding.
  31. */
  32. private Charset encoding = DEFAULT_ENCODING;
  33. /**
  34. * Whether to enable template caching.
  35. */
  36. //默认开启缓存,项目没上线建议通过配置关闭,然后按F9就可以自动编译,避免影响调试
  37. private boolean cache = true;
  38. ....
  39. }

ok,然后简单跟一下视图解析器的源码:Thymeleaf视图解析器类的关键代码,创建视图view的方法,如图,也是根据viewname进行重定向
在这里插入图片描述
从上面方法可以看出进行重定向或者forward等等方法,然后调一下redirect的,看看RedirectView类,翻下源码,找到如下关键代码:
在这里插入图片描述
同样在这个类里,进行了状态码设置,请求头设置,然后response.sendRedirect(encodedURL);
在这里插入图片描述
而forward的是通过如图方法进行页面跳转:
在这里插入图片描述

 转自  https://www.cnblogs.com/mzq123/p/11965478.html

原文链接:https://blog.csdn.net/xiao190128/article/details/117729343



所属网站分类: 技术文章 > 博客

作者:长这么胖

链接:http://www.javaheidong.com/blog/article/222311/e6cc50f3a6be320f786a/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

4 0
收藏该文
已收藏

评论内容:(最多支持255个字符)