spring boot 尚桂谷学习笔记05 ---Web
------web 开发登录功能------
修改login.html文件:注意加粗部分为 msg 字符串不为空时候 才进行显示
<!DOCTYPE html>
<!-- saved from url=(0050)http://getbootstrap.com/docs/4.0/examples/sign-in/ -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="http://getbootstrap.com/favicon.ico"> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS -->
<link href="/asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet"> <!-- Custom styles for this template -->
<link href="/asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet">
</head> <body class="text-center">
<form class="form-signin" th:action="@{/user/login}" method="post">
<img class="mb-4" src="/asserts/img/bootstrap-solid.svg" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<p style="color: red;" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
<label for="username" class="sr-only" th:text="#{login.username}">Email address</label>
<input name="username" type="email" id="username" th:placeholder="#{login.username}" class="form-control" placeholder="Email address" required="" autofocus="">
<label for="inputPassword" th:text="#{login.password}" class="sr-only">Password</label>
<input name="password" type="password" th:placeholder="#{login.password}" id="inputPassword" class="form-control" placeholder="Password" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"/> [[#{login.remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
</form>
</body></html>
添加一个controller 对应页面跳转
package com.lixuchun.springboot.controller; import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import java.util.Map; @Controller
public class LoginController { // @RequestMapping(value = "/user/login", method = RequestMethod.POST)
@PostMapping(value = "/user/login")
public String login(@RequestParam String username, @RequestParam String password
,Map<String, Object> map) {
if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
// 登录成功
return "dashboard";
} else {
map.put("msg", "用户登录失败!");
// 登录失败
return "login";
}
}
}
实现效果:填写正确情况下跳转到 dashboard.html页面中,错误情况下 返回login页面 并且显示 用户登录失败!
登录 开发期间模板引擎页面修改以后要实时生效
禁用模板引擎缓存:spring.thymeleaf.cache=false
修改页面完成以后 ctrl + f9 重新编译
当页面位于 dashboard 页面 按 F5 会有是否表单再次提交提示 (表单重复提交)
可以进行重定向防止重复提交
if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
// 登录成功
// 防止表单从夫提交 可以从定向导主页
return "redirect:/main.html";
} else {
map.put("msg", "用户登录失败!");
// 登录失败
return "login";
}
修改Mvc View视图解析器
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/main.html").setViewName("dashboard");
}
};
return adapter;
}
如果这样修改了 直接访问 localhost:8080/main.html 就可以直接访问 登录功能没起到作用 那么引入拦截器
拦截器 编写拦截器controller 必须实现 HandlerInterceptor
pre 在登录之前进行检查:
package com.lixuchun.springboot.component; import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* 进行登录检查
*/
public class LoginHandlerIntercepter implements HandlerInterceptor{ // 目标方法预检查
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginUser");
if (user == null) {
// 未登录 返回登录页面
request.setAttribute("msg", "没有用户权限 请先登录");
// 没有登录跳转到 /index.html 页面
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
} else {
// 已经登录 放行请求
return true;
}
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { }
}
Mvc 配置文件添加 Interceptor 组件 进行注册:
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/main.html").setViewName("dashboard");
} // 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 拦截任意请求
// 已经做好了静态资源的映射 *.css *.js 访问等 不需要做处理
registry.addInterceptor(new LoginHandlerIntercepter()).addPathPatterns("/**")
.excludePathPatterns("/index.html", "/", "/user/login");
}
};
return adapter;
}
访问效果:在没有登录的情况下 访问 localhost:8080/main.html
登录后再次访问:左侧上面 test@test.com 为登录名称 dashboard 页面 [[${session.loginUser}]] 行内表达式取值
CRUD-员工列表
实验要求:
1) RestfulCRUD: CRUD 满足Rest风格
URI : /资源名称/资源标识 HTTP请求方式区分对资源的CRUD操作
/emp/{id}
2). 实验的请求架构
3).员工列表
抽取公共元素片段
<div th:fragment="copy">© 2011 thymes Virtual Grocery</div>
引入公共元素片段
<div th:insert="~{footer::copy}"></div>
~{templatename::selector} :模板名 :: 选择器
~{templatename::fragmentname}:模板名::片段名
三种引入公共片段th属性:
th:insert :将公共的片段整个插入到声明引用的div中
th:replace: 将声明引入的元素替换为公共片段
th:include:被引入的片段内容包含近这个标签中
如果使用th:insert 等属性进行引入 可以不用写 ~{}
行内写法加上 [[~{}]] , [(~{})] (转义不转义)
dashboard 页面定义公共片段头 th:fragment="topbar"
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav>
list 页面头取法
<!-- 引入抽取的topbar -->
<!-- 模板名称:使用thymeleaf的配置规则进行解析 -->
<div th:replace="~{dashboard::topbar}"></div>
dashboard 页面定义公共片段侧边栏 id="sideBar"
<nav id="sideBar" class="col-md-2 d-none d-md-block bg-light sidebar" style="margin-top: 50px;">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
Dashboard <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
Orders
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
Products
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{/emps}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
员工管理
</a>
</li>
</ul>
</div>
</nav>
list 页面侧边栏取法
<!-- 引入侧边栏 -->
<div th:replace="~{dashboard::#sideBar}"></div>
也可以单独提出一个bar文件 然后在各个页面进行调用
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- top bar -->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav> <!-- side bar -->
<nav id="sideBar" class="col-md-2 d-none d-md-block bg-light sidebar" style="margin-top: 50px;">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
Products
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{/emps}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
员工管理
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layers"><polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
Integrations
</a>
</li>
</ul>
</div>
</nav>
</body>
</html>
页面进行调用 list 页面 效果和之前的效果一样
<!-- 引入抽取的topbar -->
<!-- 模板名称:使用thymeleaf的配置规则进行解析 -->
<div th:replace="commons/bar::topbar"></div>
<!-- 引入侧边栏 -->
<div th:replace="commons/bar::#sideBar"></div>
引入片段也可以传入参数:
在 dashboard.html 页面引入左侧栏时候 传入参数
<div th:replace="commons/bar::#sideBar(activeUri='main.html')"></div>
在 bar.html 页面设置左侧栏时候 通过传过来的参数设置 是否高亮
<li class="nav-item">
<a class="nav-link active" href="#"
th:href="@{/main.html}" th:class="${activeUri=='main.html'?'nav-link active':'nav-link'}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
Dashboard <span class="sr-only">(current)</span>
</a>
</li>
员工列表做数据展示:
list.html 页面编写
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<div class="chartjs-size-monitor" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;">
<div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
<div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div>
</div>
<div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
<div style="position:absolute;width:200%;height:200%;left:0; top:0">
</div>
</div>
</div>
<h2><button class="btn btn-sm btn-success">员工添加</button></h2>
<h2>Section title</h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>#</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>department</th>
<th>birth</th>
<th>options</th>
</tr>
</thead>
<tbody>
<tr th:each="emp:${emps}">
<td th:text="${emp.id}"></td>
<td>[[${emp.lastName}]]</td>
<td th:text="${emp.email}"></td>
<td th:text="${emp.gender}==0?'girl':'boy'"></td>
<td th:text="${emp.department.departmentName}"></td>
<td th:text="${#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')}"></td>
<td>
<button class="btn btn-sm btn-primary">编辑员工</button>
<button class="btn btn-sm btn-danger">删除员工</button>
</td>
</tr>
</tbody>
</table>
</div>
</main>
做一个伪处理 employeeDao
package com.lixuchun.springboot.dao; import com.lixuchun.springboot.entities.Department;
import com.lixuchun.springboot.entities.Employee;
import org.springframework.stereotype.Repository; import java.util.ArrayList;
import java.util.Date;
import java.util.List; @Repository
public class EmployeeDao {
public Employee selectEmpById(Integer id) {
return new Employee();
} public List<Employee> selectEmps() {
List<Employee> empList = new ArrayList<Employee>();
for (int i = 0; i < 6; i++) {
Employee emp = new Employee(i, "emp" + i,
i + "emp@emp.com", 0,
new Department(i, "dep"+ i), new Date());
empList.add(emp);
}
return empList;
}
}
employee / department
department
private Integer id;
private String departmentName; employee
id
lastName
gender
department
birth
EmpController 编写
@Autowired
EmployeeDao employeeDao; // 查询所有员工返回列表页面
@GetMapping("/emps")
public String list(Model model) {
List<Employee> employees = employeeDao.selectEmps();
model.addAttribute("emps", employees);
// classpath:/templates/xxx.html
return "emp/list";
}
最后页面效果:
员工添加功能:
list 添加按钮 <a class="btn btn-sm btn-success" href="emp" th:href="@{/emp}">员工添加</a>
emp get 请求到员工添加页面
emp post 添加员工
其中部门为后台查出来的,前后台处理
<select class="form-control">
<option th:value="${dept.id}" th:each="dept:${depts}" th:text="dept.departmentName"></option>
</select>
点击添加按钮 post 到 emp为添加功能
<form ah:action="@{/emp}" method="post">
员工添加controller
修改日期格式:spring.mvc.date-format=yyyy-MM-dd
员工修改:emp/id ------->get 方式
<a class="btn btn-sm btn-primary" th:href="@{/emp/} + ${emp.id}">编辑员工</a>
页面需要回显:
th:value="${emp!=null}?${emp.lastName}">
th:checked="${emp!=null}?${emp.gender==1}" / gender==0
th:selected="${emp!=null}?${dept.id==emp.department.id}"
如何发送put请求,到员工修改controller
删除:delete请求
出现了按钮换行 因为 form的添加 所以进行修改
设置按钮del_uri
button 设置 :th:attr="del_uri=@{emp/} + ${emp.id}"
form 设置:id="deleteEmpForm"
最后效果:
spring boot 尚桂谷学习笔记05 ---Web的更多相关文章
- spring boot 尚桂谷学习笔记04 ---Web开始
------web开发------ 1.创建spring boot 应用 选中我们需要的模块 2.spring boot 已经默认将这些场景配置好了 @EnableAutoConfiguration ...
- spring boot 尚桂谷学习笔记10 数据访问02 mybatis
数据访问 mybatis 创建一个 springboot 工程,模块选择 sql 中 mysql(数据驱动), jdbc(自动配置数据源), mybatis Web模块中选择 web pom 引入: ...
- spring boot 尚桂谷学习笔记11 数据访问03 JPA
整合JPA SpringData 程序数据交互结构图 (springdata jpa 默认使用 hibernate 进行封装) 使用之后就关注于 SpringData 不用再花多经历关注具体各个交互框 ...
- spring boot 尚桂谷学习笔记09 数据访问
springboot 与数据库访问 jdbc, mybatis, spring data jpa, 1.jdbc原生访问 新建项目 使用 springboot 快速构建工具 选中 web 组件 sq ...
- spring boot 尚桂谷学习笔记07 嵌入式容器 ---Web
------配置嵌入式servlet容器------ springboot 默认使用的是嵌入的Servlet(tomcat)容器 问题? 1)如何定制修改Servlet容器的相关配置: 1.修改和se ...
- spring boot 尚桂谷学习笔记08 Docker ---Web
------Docker------ 简介:Docker是一个开元的应用容器引擎,性能非常高 已经安装好的软件打包成一个镜像放到服务器中运行镜像 MySQL容器,Redis容器...... Docke ...
- spring boot 尚桂谷学习笔记06 异常处理 ---Web
------错误处理机制------ 默认效果 1 返回一个默认的错误页面 浏览器发送请求的请求头:优先接收 text/html 数据 客户端则默认响应json数据 : accept 没有说明返回什么 ...
- springboot 尚桂谷学习笔记03
------spring boot 与日志------ 日志框架: 市面上的日志框架: jul jcl jboss-logging logback log4j log4j2 ...... 左边一个门面 ...
- Spring实战第六章学习笔记————渲染Web视图
Spring实战第六章学习笔记----渲染Web视图 理解视图解析 在之前所编写的控制器方法都没有直接产生浏览器所需的HTML.这些方法只是将一些数据传入到模型中然后再将模型传递给一个用来渲染的视图. ...
随机推荐
- ubuntu18.04 搭建scrapy环境(连环踩坑+解决办法)
---恢复内容开始--- 预期需求: 打算搭建scrapy环境,基于python3.x的 环境描述: ubuntu18.04自带了python3.6,打算在虚拟环境vlenv中跑scrapy,装好虚拟 ...
- #python# 使用代理和不使用代理对比
import urllib.request url='http://httpbin.org/ip' #不使用代理 response1=urllib.request.urlopen(url) #设置代理 ...
- 2019牛客暑期多校训练营(第一场) - H - XOR - 线性基
https://ac.nowcoder.com/acm/contest/881/H 题意: 给定n个整数,求其中异或和为 \(0\) 的子集的大小的和. 题解思路: 首先转化为每个可以通过异或表示 \ ...
- python 注释有哪些和作用
python 单行注释 #作为代表 python 多行注释 ‘’‘ 这是三个单引号注释 ’‘’ “”“ 这是三个双引号注释 ”“”
- grep命令用关系或查询多个字符串
bcmsh ps | grep -E 'port|ge2 ' bcmsh ps | grep 'port\|ge2 ' 我的目的是筛选出含有 ‘port’ 或者含有 ‘ge2 ’ 的行,上面的第一行参 ...
- gulp run 报错 gulp[3192]: src\node_contextify.cc:628: Assertion `args[1]->IsString()' failed.
由于把node升级到了10以上的版本 执行gulp rjs打包文件报错,错误如下: gulp[3192]: src\node_contextify.cc:628: Assertion `args[1] ...
- BUUCTF--xor
测试文件:https://buuoj.cn/files/caa0fdad8f67a3115e11dc722bb9bba7/7ea34089-68ff-4bb7-8e96-92094285dfe9.zi ...
- AJAX - 实现一个简单的登录验证
/**Ajax 编写流程 * 1.创建 XHR (XMLHttpRequest)对象 var xmlHttpReq = false; // var xmlHttpReq = ""; ...
- elasticsearch 深入 —— Search Type检索类型
在此我们再给出那个查询的代码: $ curl -XGET localhost:9200/startswith/test/_search?pretty -d '{ "query": ...
- ajax中的application/x-www-form-urlencoded中的使用[转]
一,HTTP上传的基本知识 在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型.下边是说明: application/x-w ...