上一级页面:ssm-spring-boot速成学习索引
前言
44、web实验-后台管理系统基本功能
项目创建
使用IDEA的Spring Initializr。
thymeleaf、
web-starter、
devtools、
lombok
登陆页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <html lang ="en" xmlns:th ="http://www.thymeleaf.org" > <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 >
thymeleaf内联写法:
1 <p > Hello, [${session.user.name}](/spring-boot-web-%E5%BC%80%E5%8F%91-5/../${session.user.name})!</p >
登录控制层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 @Controller public class IndexController { @GetMapping(value = {"/","/login"}) public String loginPage () { return "login" ; } @PostMapping("/login") public String main (User user, HttpSession session, Model model) { if (StringUtils.hasLength(user.getUserName()) && "123456" .equals(user.getPassword())){ session.setAttribute("loginUser" ,user); return "redirect:/main.html" ; }else { model.addAttribute("msg" ,"账号密码错误" ); return "login" ; } } @GetMapping("/main.html") public String mainPage (HttpSession session, Model model) { Object loginUser = session.getAttribute("loginUser" ); if (loginUser != null ){ return "main" ; }else { model.addAttribute("msg" ,"请重新登录" ); return "login" ; } } }
模型
1 2 3 4 5 6 7 @AllArgsConstructor @NoArgsConstructor @Data public class User { private String userName; private String password; }
45、web实验-抽取公共页面
官方文档 - Template Layout
公共页面/templates/common.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 <!DOCTYPE html > <html lang ="en" xmlns:th ="http://www.thymeleaf.org" > <head th:fragment ="commonheader" > <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 > <div id ="leftmenu" class ="left-side sticky-left-side" > ... <div class ="left-side-inner" > ... <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 > </div > </div > <div th:fragment ="headermenu" class ="header-section" > <a class ="toggle-btn" > <i class ="fa fa-bars" > </i > </a > ... </div > <div id ="commonscript" > <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 > <script th:src ="@{/js/scripts.js}" > </script > </div > </body > </html >
/templates/table/basic_table.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <!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 > </head > <body class ="sticky-header" > <section > <div th:replace ="common :: #leftmenu" > </div > <div class ="main-content" > <div th:replace ="common :: headermenu" > </div > ... </div > </section > <div th:replace ="common :: #commonscript" > </div > </body > </html >
Difference between th:insert
and th:replace
(and th:include
)
46、web实验-遍历数据与页面bug修改
控制层代码:
1 2 3 4 5 6 7 8 9 10 11 @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" ; }
页面代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <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}](/spring-boot-web-%E5%BC%80%E5%8F%91-5/../${user.password})</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模式运行实例,这样比较没那么沉闷。
SpringBootWeb开发-6
spring-boot-web-开发-6
参考、引用、致谢