前面已经学习了SpringBoot的一些请求和响应,以及自动配置的一些原理,现在来学习视图解析。
一、视图解析
(一)初体验视图解析
1、什么是视图解析
视图解析其实就是SpringBoot某一个controller的方法执行完成之后,它是跳转到那个页面。由于我们springboot项目默认打包为jar包,是形成压缩包的形式,而jsp又不支持压缩,所以我们SpringBoot不知JSP的,需要引入第三方模板引擎才可以处理{常用的有:· Thymeleaf · FreeMarker · Velocity · Groovy · Mustache· JSP}。
2、Thymeleaf概念
它可以在单体应用中使用,不建议在高并发项目下使用。现代化、服务端Java模板引擎
1)基本语法
(1)基本表达式
(2)字面量
- 文本值: ‘one text’ , ‘Another one!’ ,…数字: 0 , 34 , 3.0 , 12.3 ,…布尔值: true , false
- 空值: null
- 变量: one,two,… 变量不能有空格
(3)文字操作
- 字符串拼接: +
- 变量替换: |The name is ${name}|
(4)数字运行
运算符: + , - , * , / , %
(5)布尔运算
运算符: and , or
一元运算: ! , not
(6)比较运算
比较: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne )
(7)条件运算
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
(8)特殊操作
无操作: _
2)设置属性值:th:attr=“xx”
- 设置单个值
<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}">
3)迭代
<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>
4)条件运行
<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>
5)属性的优先级
3、使用Thymeleaf
1)依赖问题
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2)配置Thymeleaf
(1)首先来看个大概流程
- 自动配好的如下
- 模板解析器
- 视图解析器
- 我们只要直接开发页面即可。
- 模板解析器
(2)一些小规则
根据这个如果你没有配置的话,那按着默认的来,那么就进行上面的配置,文件方在类路径下的templates下的,而且后缀为.html
- 如果要修改就在配置文件里面写,暂时不讲。
(3)引入一个模板
<html lang="en" xmlns:th="http://www.thymeleaf.org">
(4)编写controller
- 对controller要求为:要跳转就用controller,而不能用RestController
- 对于取值
- 启动测试【但是对于这个百度首页为什么呢,可以等一下再看】
好吧是我自己傻逼了【百度首页是a标签】
(二)搭建项目玩玩
1、建项目
(1)导入前端项目
导入如下在static
这个页面呢,可以自己去找了下载。
2、编写controller
3、去主页面
- th:action=@{/login}
- 这里哟啊特殊处理,因为我们登录进去之后,不能刷新后,不能重复提交。
- 可以对这个control模拟个大概
@PostMapping("/login")
public String main(User user, HttpSession session, Model model){
if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){
//把登陆成功的用户保存起来
session.setAttribute("loginUser",user);
//登录成功重定向到main.html; 重定向防止表单重复提交
return "redirect:/main.html";
}else {
model.addAttribute("msg","账号密码错误");
//回到登录页面
return "login";
}
}
4、模板抽取
我们把所有页面共同的,把它抽取放到统一的XXX.html里面,在那个点需要就在哪个点引入如下。
-
th:fragment=“xxx”【取名为xxx】
-
th:insert/replace/include【在某一个点引入即可】
(三)视图解析器与视图
上面呢有个了解就行了,现在很多情况下是使用Vue进行处理,有需要在赶快去补习。
1、重定向打断点
上面种就不用说了,之前的笔记中就已经打过断点一点点的分析了。
- 首先肯定是要在DispatcherServlet类里面
到了上面步骤后,点两次进入后,都直接放行到这一步
然后继续点放行里面的过程走了,会经过如下。- 目标方法处理的过程中,所有数据都会被放在 ModelAndViewContainer 里面。包括数据和视图地址(我们的redirect:/success.html)
- 方法的参数是一个自定义类型对象(从请求参数中确定的),把他重新放在 ModelAndViewContainer
- 任何目标方法执行完成以后都会返回 ModelAndView(数据和视图地址)。
在上面的过程就经过的过程,提取到的主要信息。
- 处理回到了这里
上面的这一步【处理派发结果】
- processDispatchResult 处理派发结果(页面改如何响应)
进入这一步
- 调用render进行页面渲染
根据方法的String返回值得到这里面会判断是是否国际化哦,其中得到View对象(此对象定义了页面的渲染逻辑) - 这里又开始遍历,遍历视图解析器
- 我们的redirect开头的String得到了一个RedirectView
- 通过得到了 redirect:/main.html 进而得到 Thymeleaf new RedirectView()
- ContentNegotiationViewResolver 里面包含了下面所有的视图解析器,内部还是利用下面所有视图解析器得到视图对象。
- view.render(mv.getModelInternal(), request, response); 视图对象调用自定义的render进行页面渲染工作
- RedirectView如何渲染(重定向到一个页面)
- 获取目标url地址
- response.sendRedirect(encodedURL)
- RedirectView如何渲染(重定向到一个页面)
- 同样的如果写了如下的页面效果
- new InternalResourceView(forwardUrl); --> 转发request.getRequestDispatcher(path).forward(request, response);
- forward底层是转发,不是重定向。
- 调用render进行页面渲染
2、forward和redirect区别
- 重定向是再一次像浏览器一样再次请求一次(它比较安全)
- 转发是在服务器内部进行处理,跳转到另外一个页面(它比较危险)
具体的可以看看这篇文章:https://blog.csdn.net/weixin_38447888/article/details/106315971
2、小结
对于这里建议观看文章的朋友打个断点,自己看看,不太好写,中间要写详细的话,截屏太多了。