spring boot系列02--Thymeleaf+Bootstrap构建页面
上一篇说了一下怎么构建spring boot 项目
接下来我们开始讲实际应用中需要用到的 先从页面说起
页面侧打算用Thymeleaf+Bootstrap来做
先共通模板页
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <body> <!-- Header --> <div th:fragment="header(title)"> <div> <h2>Guaishushu</h2> </div> </div> <!-- Footer --> <div th:fragment="footer" class="navbar-fixed-bottom"> <div class="container text-center"> Copyright © GuaiShuShu </div> </div> </body> </html>
暂且定义两个共通 Header 和 Footer 之后还会再有 比如 menu 的
这里能说的就是th:fragment
开始说了 页面用 Thymeleaf+Bootstrap 来做
th就是Thymeleaf的缩写了 它用【th:】来告诉解析器这里是Thymeleaf的东西了
(关于Thymeleaf的东西这里打算是用哪儿写哪儿 不打算系统写 之后可能会系统写一个Thymeleaf的系列)
说一下代码里的两个 两个模板
th:fragment="header(title) 是表示 名叫 header 有参 的模板
th:fragment="footer" 这个就是 无参的了
接下来看看调用的地方 L21,L79
模板画面名(common)+模板名(header)+参数( 'login')
1 <!DOCTYPE HTML> 2 <!-- thymeleaf 导入 --> 3 <html xmlns:th="http://www.thymeleaf.org"> 4 <head> 5 <title>登录</title> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 7 <script type="text/javascript" src="../static/js/jquery-3.2.1.min.js"></script> 8 <link rel="stylesheet" href="../static/css/bootstrap.min.css" 9 type="text/css"></link> 10 <script type="text/javascript"> 11 $(function() { 12 }) 13 </script> 14 <body> 15 <!-- common 的 定义好的 header模板 引用 参数 title --> 16 <!-- 17 Bootstrap的容器Class使用 18 container :用于固定宽度并支持响应式布局的容器 19 container-fluid :用于 100% 宽度,占据全部视口(viewport)的容器。 20 --> 21 <div class="container" th:replace="common :: header('login') "></div> 22 <div class="container"> 23 <!--Bootstrap 24 .row:行控制 一行有12列 25 .clo-md-4:列控制 表示 占 4列 26 .md-offfset-4:向右侧偏移4 27 --> 28 <div class="row"> 29 <div class="col-md-4 col-md-offset-4"> 30 <div class="panel panel-default"> 31 <div class="panel-heading"> 32 <h3 class="panel-title">Login</h3> 33 </div> 34 <div class="panel-body"> 35 <form th:action="@{'/login'}" method="post" th:object="${userDto}"> 36 <div class="form-group form-inline"> 37 <label for="txtUserName" class="col-md-3 control-label" 38 style="text-align: right;">用户名</label> 39 <div class="col-md-9"> 40 <input type="text" class="col-md-9 form-control" id="txtUserName" 41 placeholder="请输入用户名" th:field="*{userName}" 42 required="required" /> 43 </div> 44 </div> 45 <div class="form-group form-inline" style="padding-top:45px"> 46 <label for="txtUserPwd" class="col-sm-3 control-label" 47 style="text-align: right;">密码</label> 48 <div class="col-md-9"> 49 <input type="password" class="col-sm-9 form-control" id="txtUserPwd" 50 placeholder="请输入密码" th:field="*{userPsw}" /> 51 </div> 52 </div> 53 <div class="form-group"> 54 <div class="col-md-offset-3 col-md-9"> 55 <div class="checkbox"> 56 <label> <input type="checkbox" />请记住我 57 </label> 58 </div> 59 </div> 60 </div> 61 <div class="form-group"> 62 <div class="col-md-offset-3 col-md-5"> 63 <button class="btn btn-primary btn-block" type="submit" name="action" 64 value="login">登录</button> 65 </div> 66 67 </div> 68 <div class="alert alert-danger" th:if="${loginError}"> 69 <strong>用户名或者用户密码不正确,请重新输入</strong> 70 </div> 71 </form> 72 </div> 73 </div> 74 </div> 75 </div> 76 </div> 77 78 <!-- common 的 定义好的 fotter模板引用 无参 --> 79 <div class="container" th:replace="common :: footer"></div> 80 </body> 81 </head> 82 </html>
说一下thymeleaf使用的地方
L35 使用或者说定义了一个userDto对象
说使用是因为 这个对象你得重后台传给它否则报错
说定义 是因为 在当前from作用于域内 像L41那样去访问使用userDto这个对象内属性/方法
关于Bootstrap的部分 我基本都在代码的注释里写了
这里就不赘述了 看一下Controller
1 package com.sts.springboot.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.ui.Model; 5 import org.springframework.web.bind.annotation.ModelAttribute; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RequestMethod; 8 import org.springframework.web.bind.annotation.RequestParam; 9 import org.springframework.web.servlet.mvc.support.RedirectAttributes; 10 11 import com.sts.springboot.dto.UserDto; 12 13 @Controller 14 public class LoginController { 15 16 //初期化 17 @RequestMapping(value = "/login", method = RequestMethod.POST) 18 public String login(Model model) { 19 UserDto userDto = new UserDto(); 20 model.addAttribute("userDto",userDto); 21 return "login"; 22 } 23 24 //登录 25 @RequestMapping(value = "/login",params="action=login", method = RequestMethod.POST) 26 public String login(@RequestParam(value = "userName") String userName, 27 @RequestParam(value = "userPsw") String userPsw,Model model,RedirectAttributes redirectAttributes ) { 28 UserDto userDto = new UserDto(); 29 if(userName.equals(userPsw)) { 30 redirectAttributes.addFlashAttribute("userName",userName); 31 return "redirect:index"; 32 } else { 33 model.addAttribute("loginError",true); 34 model.addAttribute("userDto",userDto); 35 return "login"; 36 } 37 } 38 @RequestMapping("/index") 39 public String welcomeIndex(@ModelAttribute("userName") String userName,Model model) { 40 model.addAttribute("userName",userName); 41 return "index"; 42 } 43 44 }
简单说一下,先说参数部分
@RequestParam 使用来接收前台穿过来的参数 不用赘述 有一点 @RequestParam的value 是要和 页面上 th:field="*{userPsw}" 的保持一致的
Model model 这是 页面的对象返回时作为传参的载体使用
RedirectAttributes 是重定向传参用的 像L30那样 set进去 L39 接受 L40 set 到新页面的model里
然后
主要逻辑是 判断 用户名是否等于用户密码
是 重定向到 index 页面 显示
否 想页面 返回error 提示
贴一下index 的代码
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Insert title here</title> </head> <body> <div class="container" th:replace="common :: header('login') "></div> <div class="container"> 欢迎,<span th:text="${userName}"></span>登录 </div> <div class="container" th:replace="common :: footer"></div> </body> </html>
最后整体看一下效果
GitHub:spring-boot-hello