124.【SpringBoot 源码刨析C】(三)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 124.【SpringBoot 源码刨析C】
5.视图解析与模板引擎

视图解析:SpringBoot默认不支持 JSP,需要引入第三方模板引擎技术实现页面渲染

(1).视图解析
(1.1)、视图解析原理流程

1、目标方法处理的过程中,所有数据都会被放在 ModelAndViewContainer 里面。包括数据和视图地址

2、方法的参数是一个自定义类型对象(从请求参数中确定的),把他重新放在 ModelAndViewContainer

3、任何目标方法执行完成以后都会返回 ModelAndView(数据和视图地址)。

4、processDispatchResult 处理派发结果(页面该如何响应)

DisplatchServlet的 第1078行
  • 1、render(mv, request, response); 进行页面渲染逻辑
  • 1、根据方法的String返回值得到 View 对象【定义了页面的渲染逻辑】
  • 1、所有的视图解析器尝试是否能根据当前返回值得到View对象 (for遍历尝试)
  • 2、得到了 redirect:/main.html --> Thymeleaf new RedirectView()
  • 3、ContentNegotiationViewResolver 里面包含了下面所有的视图解析器,内部还是利用下面所有视图解析器得到视图对象。
  • 4、view.render(mv.getModelInternal(), request, response); 视图对象调用自定义的render进行页面渲染工作
  • view.render(mv.getModelInternal(), request, response); 1393行
  • RedirectView类 如何渲染【重定向到一个页面】
  • 1、获取目标url地址
  • 2、response.sendRedirect(encodedURL);

视图解析:

  • 返回值以 forward: 开始: new InternalResourceView(forwardUrl); --> 转发request.getRequestDispatcher(path).forward(request, response);
  • 返回值以 redirect: 开始: new RedirectView() --》 render就是重定向
(2).Thymeleaf基本语法
(2.1)、表达式

(2.2)、字面量

文本值: ‘one text’ , ‘Another one!’ ,…数字: 0 , 34 , 3.0 , 12.3 ,…布尔值: true , false

空值: null

变量: one,two,… 变量不能有空格

(2.3)、文本操作

字符串拼接: +

变量替换: |The name is ${name}|

(2.4)、数学运算

运算符: + , - , * , / , %

(2.5)、布尔运算

运算符: and , or

一元运算: ! , not

(2.6)、比较运算

比较: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne )

(2.7)、条件运算

If-then: (if) ? (then)

If-then-else: (if) ? (then) : (else)

Default: (value) ?: (defaultvalue)

(2.8)、特殊操作

无操作: _

(2.9)、设置属性值-th:attr

设置单个值

<form action="subscribe.html" th:attr="action=@{/subscribe}">
  <fieldset>
    <input type="text" name="email" />
    <input type="submit" value="Subscribe!" th:attr="value=#{subscribe.submit}"/>
  </fieldset>
</form>

设置多个值

<img src="../../images/gtvglogo.png"  th:attr="src=@{/images/gtvglogo.png},title=#{logo},alt=#{logo}" />

以上两个的代替写法 th:xxxx

<input type="submit" value="Subscribe!" th:value="#{subscribe.submit}"/>
<form action="subscribe.html" th:action="@{/subscribe}">

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#setting-value-to-specific-attributes

行内写法

1. 假如要写的内容不在标签中而在行内,那么就用这个方式。(非session)
<h1>[[${xxx}]]</h1>
2. 假如是取Session的值
<h1>[[$session.name.xxx}]]</h1>
(2.10)、迭代
<tr th:each="prod : ${prods}">
        <td th:text="${prod.name}">Onions</td>
        <td th:text="${prod.price}">2.41</td>
        <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'">
  <td th:text="${prod.name}">Onions</td>
  <td th:text="${prod.price}">2.41</td>
  <td th:text="${prod.inStock}? #{true} : #{false}">yes</td>
</tr>
(2.11)、条件运算
<a href="comments.html"
th:href="@{/product/comments(prodId=${prod.id})}"
th:if="${not #lists.isEmpty(prod.comments)}">view</a>
<div th:switch="${user.role}">
  <p th:case="'admin'">User is an administrator</p>
  <p th:case="#{roles.manager}">User is a manager</p>
  <p th:case="*">User is some other thing</p>
</div>
(3).Thymeleaf的使用
(3.1)、引入依赖
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
(3.2)、自动配置好了thymeleaf

ThymeleafAutoConfiguration 类

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ThymeleafProperties.class)
@ConditionalOnClass({ TemplateMode.class, SpringTemplateEngine.class })
@AutoConfigureAfter({ WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class })
public class ThymeleafAutoConfiguration { }

自动配好的策略

  • 1、所有thymeleaf的配置值都在 ThymeleafProperties 类
  • 2、配置好了SpringTemplateEngine
  • 3、配好了ThymeleafViewResolver
  • 4、我们只需要直接开发页面

(3.2)、页面开发
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Success</h1>
<h1 th:text="${A}"></h1>
<a th:href="${baidu}">点击我去金橘社区 ${baidu}</a>
<br>
<br>
<a th:href="@{baidu}">点击我去金橘社区 @{baidu}</a>
<br>
<br>
<a th:href="@{/baidu}">点击我去金橘社区 @{/baidu}</a>
</body>
</html>
package com.jsxs.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
/**
 * @Author Jsxs
 * @Date 2023/7/7 17:30
 * @PackageName:com.jsxs.controller
 * @ClassName: ViewTestController
 * @Description: TODO
 * @Version 1.0
 */
@Controller
public class ViewTestController {
    @GetMapping("/toTest")
    public String toTest(Model model){
        // model 会自动放入到请求域中和HttpRequest是一样的,只能接受一次请求的操作
        model.addAttribute("A","a");
        model.addAttribute("baidu","https://www.jsxs1.cn");
        return "success";   // 假如说没有模板解析器的话,这里的路径会报黄。
    }
}
# 给整个服务器添加前缀
server:
  servlet:
    context-path: /jsxs

(4).后台管理系统总结
1. 假如在template中再新建包的话,我们只需要在 controller 的返回值中添加上新建包路径即可  /新建包名/xxx。
2. controller 页面跳转的实质是转发;不是重定向。
3. return: 的值会默认拼接  templates/xxxx.html; return forward: return redirect 找的都是请求的路径不是页面。
4. 静态资源只要放在四大区域就行,前端调用的时候可以省略掉前面的四大区域路径只写相对路径即可。
5. 抽取公共模板(第一种)
  (1). 公共页(top.html): 在标签中设置  th:fragment="AAAA"
    eg: <div  th:fragment="AAAA"></div>
  (2). 使用公共页方: th:insert="~{公共页的HTML名字 :: AAAA}"
    eg:   1. <div th:insert="~{top :: AAAA}"></div> 
      或 2.<div th:insert="top :: AAAA"></div>   
      或 3.<div th:replace="~{top :: utopbar}"></div>
      或 4.<div th:include="~{top :: topbar}"></div>
  假如说公共页面和被添加公共页面不再同一个包中那么就要加上路径指定在哪
    eg:<div th:include="~{commons/top :: topbar}"></div>
6.抽取公共模板(第二种 ->选择器方式)
  (1). 公共页(top.html): 在标签中设置  id="BBB"
  (2). 使用方: <div th:replace="top :: #BBB"> (当然以上的几种方法都适用)

公共方:

<footer th:fragment="copy">
  &copy; 2011 The Good Thymes Virtual Grocery
</footer>
• 1
• 2
• 3

使用公共方

<body>
  ...
  会带上div(全部都要)
  <div th:insert="~{footer :: copy}"></div>
  引入的东西不会在div里面
  <div th:replace="~{footer :: copy}"></div>
    引入的中西会在div里面
  <div th:include="~{footer :: copy}"></div>
</body>

实际效果:

假如引入的是css、js。也是一样的只不过把div改为link或script
<body>
  ...
  <div>
    <footer>
      &copy; 2011 The Good Thymes Virtual Grocery
    </footer>
  </div>
  <footer>
    &copy; 2011 The Good Thymes Virtual Grocery
  </footer>
  <div>
      &copy; 2011 The Good Thymes Virtual Grocery
  </div>
</body>
(4.1)、举列子(公共方)

1.公共方的页面

2.replace->引入的东西会在link标签里面内嵌link标签

<link th:replace="~{}">

相关文章
|
2月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
3月前
|
前端开发 Java
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
文章通过一个表白墙/留言墙的初级SpringBoot项目实例,详细讲解了如何进行前后端开发,包括定义前后端交互接口、创建SpringBoot项目、编写前端页面、后端代码逻辑及实体类封装的全过程。
108 3
表白墙/留言墙 —— 初级SpringBoot项目,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
3月前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
476 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
9天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
20天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
101 13
|
27天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
2月前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
3月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
221 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
3月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
86 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
3月前
|
机器学习/深度学习 移动开发 自然语言处理
基于人工智能技术的智能导诊系统源码,SpringBoot作为后端服务的框架,提供快速开发,自动配置和生产级特性
当身体不适却不知该挂哪个科室时,智能导诊系统应运而生。患者只需选择不适部位和症状,系统即可迅速推荐正确科室,避免排错队浪费时间。该系统基于SpringBoot、Redis、MyBatis Plus等技术架构,支持多渠道接入,具备自然语言理解和多输入方式,确保高效精准的导诊体验。无论是线上医疗平台还是大型医院,智能导诊系统均能有效优化就诊流程。