------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">&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
email
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的更多相关文章

  1. spring boot 尚桂谷学习笔记04 ---Web开始

    ------web开发------ 1.创建spring boot 应用 选中我们需要的模块 2.spring boot 已经默认将这些场景配置好了 @EnableAutoConfiguration ...

  2. spring boot 尚桂谷学习笔记10 数据访问02 mybatis

    数据访问 mybatis 创建一个 springboot 工程,模块选择 sql 中 mysql(数据驱动), jdbc(自动配置数据源), mybatis Web模块中选择 web pom 引入: ...

  3. spring boot 尚桂谷学习笔记11 数据访问03 JPA

    整合JPA SpringData 程序数据交互结构图 (springdata jpa 默认使用 hibernate 进行封装) 使用之后就关注于 SpringData 不用再花多经历关注具体各个交互框 ...

  4. spring boot 尚桂谷学习笔记09 数据访问

    springboot 与数据库访问 jdbc, mybatis, spring data jpa,  1.jdbc原生访问 新建项目 使用 springboot 快速构建工具 选中 web 组件 sq ...

  5. spring boot 尚桂谷学习笔记07 嵌入式容器 ---Web

    ------配置嵌入式servlet容器------ springboot 默认使用的是嵌入的Servlet(tomcat)容器 问题? 1)如何定制修改Servlet容器的相关配置: 1.修改和se ...

  6. spring boot 尚桂谷学习笔记08 Docker ---Web

    ------Docker------ 简介:Docker是一个开元的应用容器引擎,性能非常高 已经安装好的软件打包成一个镜像放到服务器中运行镜像 MySQL容器,Redis容器...... Docke ...

  7. spring boot 尚桂谷学习笔记06 异常处理 ---Web

    ------错误处理机制------ 默认效果 1 返回一个默认的错误页面 浏览器发送请求的请求头:优先接收 text/html 数据 客户端则默认响应json数据 : accept 没有说明返回什么 ...

  8. springboot 尚桂谷学习笔记03

    ------spring boot 与日志------ 日志框架: 市面上的日志框架: jul jcl jboss-logging logback log4j log4j2 ...... 左边一个门面 ...

  9. Spring实战第六章学习笔记————渲染Web视图

    Spring实战第六章学习笔记----渲染Web视图 理解视图解析 在之前所编写的控制器方法都没有直接产生浏览器所需的HTML.这些方法只是将一些数据传入到模型中然后再将模型传递给一个用来渲染的视图. ...

随机推荐

  1. 用bootstrap和css3制作按钮式下拉菜单

    利用bootstrap框架的字体图标和下拉菜单效果,以及css3的动画效果,可以做出比较优雅的按钮式下拉菜单样式 <style> .myBtnStyle .dropdown-menu sp ...

  2. jar包 war包

    jar包和war包的区别: war是一个web模块,其中需要包括WEB-INF,是可以直接运行的WEB模块.而jar一般只是包括一些class文件,在声明了Main_class之后是可以用java命令 ...

  3. CodeChef Count Substrings

    Count Substrings   Problem code: CSUB   Submit All Submissions   All submissions for this problem ar ...

  4. Java 小技巧和在Java避免NullPonintException的最佳方法(翻译)

                前几天就g+里面看到有人引用这篇博文.看了一下.受益颇多. 所以翻译过来,希望和大家一起学习.本人英语水平有限,假设有错,请大家指正. 原文地址(须要翻墙):http://ja ...

  5. ubuntu 系统类似QQ截图工具:DeepinScrot,flameshot

    经过一番探索! Ubuntu16.04 就用DeepinScrot 好用!不支持flameshot,反正我是半天没装成功 教程:https://blog.csdn.net/qq_19339041/ar ...

  6. elasticsearch 基础 —— 集群原理

    空集群 如果我们启动了一个单独的节点,里面不包含任何的数据和 索引,那我们的集群看起来就是一个 图 1 "包含空内容节点的集群". 图 1. 包含空内容节点的集群 一个运行中的 E ...

  7. Mac版Navicat Premium激活教程

    工具: Navicat Premium12.0.20 安装包 下载注册机工具包 链接:https://pan.baidu.com/s/1NS8gk780ds1Xn-zHrSIzIw  密码:dvke ...

  8. ActiveMQ修改端口号

    1.修改tcp端口号 安装目录下的conf/activemq.xml 2.修改管理页面的访问端口号 安装目录下的conf/jetty.xml

  9. rabbit 独占队列

    std::string queue_name = "hello"; AmqpClient::Channel::ptr_t channel = AmqpClient::Channel ...

  10. pwn的一些技巧与总结

    原文地址:https://github.com/Naetw/CTF-pwn-tips 目录 溢出 在gdb中寻找字符串 二进制服务 找到libc中特定函数的偏移地址 Find '/bin/sh' or ...