SpringBootWeb开发-5
2023年1月22日大约 4 分钟
上一级页面:ssm-spring-boot速成学习索引
前言
44、web实验-后台管理系统基本功能
项目创建
使用IDEA的Spring Initializr。
- thymeleaf、
- web-starter、
- devtools、
- lombok
登陆页面
/static
放置 css,js等静态资源/templates/login.html
登录页
<html lang="en" xmlns:th="http://www.thymeleaf.org"><!-- 要加这玩意thymeleaf才能用 -->
<form class="form-signin" action="index.html" method="post" th:action="@{/login}">
...
<!-- 消息提醒 -->
<label style="color: red" th:text="${msg}"></label>
<input type="text" name="userName" class="form-control" placeholder="User ID" autofocus>
<input type="password" name="password" class="form-control" placeholder="Password">
<button class="btn btn-lg btn-login btn-block" type="submit">
<i class="fa fa-check"></i>
</button>
...
</form>
/templates/main.html
主页
thymeleaf内联写法:
<p>Hello, [${session.user.name}](${session.user.name}.md)!</p>
登录控制层
@Controller
public class IndexController {
/**
* 来登录页
* @return
*/
@GetMapping(value = {"/","/login"})
public String loginPage(){
return "login";
}
@PostMapping("/login")
public String main(User user, HttpSession session, Model model){ //RedirectAttributes
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";
}
}
/**
* 去main页面
* @return
*/
@GetMapping("/main.html")
public String mainPage(HttpSession session, Model model){
//最好用拦截器,过滤器
Object loginUser = session.getAttribute("loginUser");
if(loginUser != null){
return "main";
}else {
//session过期,没有登陆过
//回到登录页面
model.addAttribute("msg","请重新登录");
return "login";
}
}
}
模型
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private String userName;
private String password;
}
45、web实验-抽取公共页面
- 公共页面
/templates/common.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><!--注意要添加xmlns:th才能添加thymeleaf的标签-->
<head th:fragment="commonheader">
<!--common-->
<link href="css/style.css" th:href="@{/css/style.css}" rel="stylesheet">
<link href="css/style-responsive.css" th:href="@{/css/style-responsive.css}" rel="stylesheet">
...
</head>
<body>
<!-- left side start-->
<div id="leftmenu" class="left-side sticky-left-side">
...
<div class="left-side-inner">
...
<!--sidebar nav start-->
<ul class="nav nav-pills nav-stacked custom-nav">
<li><a th:href="@{/main.html}"><i class="fa fa-home"></i> <span>Dashboard</span></a></li>
...
<li class="menu-list nav-active"><a href="#"><i class="fa fa-th-list"></i> <span>Data Tables</span></a>
<ul class="sub-menu-list">
<li><a th:href="@{/basic_table}"> Basic Table</a></li>
<li><a th:href="@{/dynamic_table}"> Advanced Table</a></li>
<li><a th:href="@{/responsive_table}"> Responsive Table</a></li>
<li><a th:href="@{/editable_table}"> Edit Table</a></li>
</ul>
</li>
...
</ul>
<!--sidebar nav end-->
</div>
</div>
<!-- left side end-->
<!-- header section start-->
<div th:fragment="headermenu" class="header-section">
<!--toggle button start-->
<a class="toggle-btn"><i class="fa fa-bars"></i></a>
<!--toggle button end-->
...
</div>
<!-- header section end-->
<div id="commonscript">
<!-- Placed js at the end of the document so the pages load faster -->
<script th:src="@{/js/jquery-1.10.2.min.js}"></script>
<script th:src="@{/js/jquery-ui-1.9.2.custom.min.js}"></script>
<script th:src="@{/js/jquery-migrate-1.2.1.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/js/modernizr.min.js}"></script>
<script th:src="@{/js/jquery.nicescroll.js}"></script>
<!--common scripts for all pages-->
<script th:src="@{/js/scripts.js}"></script>
</div>
</body>
</html>
/templates/table/basic_table.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="description" content="">
<meta name="author" content="ThemeBucket">
<link rel="shortcut icon" href="#" type="image/png">
<title>Basic Table</title>
<div th:include="common :: commonheader"> </div><!--将common.html的代码段 插进来-->
</head>
<body class="sticky-header">
<section>
<div th:replace="common :: #leftmenu"></div>
<!-- main content start-->
<div class="main-content" >
<div th:replace="common :: headermenu"></div>
...
</div>
<!-- main content end-->
</section>
<!-- Placed js at the end of the document so the pages load faster -->
<div th:replace="common :: #commonscript"></div>
</body>
</html>
Difference between th:insert
and th:replace
(and th:include
)
46、web实验-遍历数据与页面bug修改
控制层代码:
@GetMapping("/dynamic_table")
public String dynamic_table(Model model){
//表格内容的遍历
List<User> users = Arrays.asList(new User("zhangsan", "123456"),
new User("lisi", "123444"),
new User("haha", "aaaaa"),
new User("hehe ", "aaddd"));
model.addAttribute("users",users);
return "table/dynamic_table";
}
页面代码:
<table class="display table table-bordered" id="hidden-table-info">
<thead>
<tr>
<th>#</th>
<th>用户名</th>
<th>密码</th>
</tr>
</thead>
<tbody>
<tr class="gradeX" th:each="user,stats:${users}">
<td th:text="${stats.count}">Trident</td>
<td th:text="${user.userName}">Internet</td>
<td >[${user.password}](${user.password}.md)</td>
</tr>
</tbody>
</table>
47、视图解析-【源码分析】-视图解析器与视图
视图解析原理流程:
- 目标方法处理的过程中(阅读
DispatcherServlet
源码),所有数据都会被放在ModelAndViewContainer
里面,其中包括数据和视图地址。 - 方法的参数是一个自定义类型对象(从请求参数中确定的),把他重新放在
ModelAndViewContainer
。 - 任何目标方法执行完成以后都会返回
ModelAndView
(数据和视图地址)。 processDispatchResult()
处理派发结果(页面改如何响应)render(mv, request, response);
进行页面渲染逻辑- 根据方法的
String
返回值得到View
对象【定义了页面的渲染逻辑】
- 所有的视图解析器尝试是否能根据当前返回值得到
View
对象 - 得到了
redirect:/main.html --> Thymeleaf new RedirectView()
。 ContentNegotiationViewResolver
里面包含了下面所有的视图解析器,内部还是利用下面所有视图解析器得到视图对象。view.render(mv.getModelInternal(), request, response);
视图对象调用自定义的render进行页面渲染工作。
RedirectView
如何渲染【重定向到一个页面】- 获取目标url地址
response.sendRedirect(encodedURL);
- 根据方法的
视图解析:
- 返回值以 `forward:` 开始: `new InternalResourceView(forwardUrl);` --> 转发`request.getRequestDispatcher(path).forward(request, response);`
- 返回值以 `redirect:` 开始: `new RedirectView()` --> render就是重定向
- 返回值是普通字符串:`new ThymeleafView()`--->
阅读源码:最好自己在IDE,打断点,且Debug模式运行实例,这样比较没那么沉闷。