SpringBoot 后台管理系统

登录功能及记住密码

防止重复提交表单 : 经过一层重定向 /realLogin 无论怎么刷新也是刷新重定向之后的网页 不会重复提交表单 ;

记住密码:存放登录用户名的cookie到本地 用户名经过MD5加密 定义一个Cookie类存放数据 经过首页的时候遍历已有cookie 判断是否存在该cookie 如果有 就直接跳转到首页

Controller 层代码

package com.manager.demo.controller;

import com.manager.demo.bean.MyCookie;
import com.manager.demo.bean.User;
import com.manager.demo.utils.MD5Util;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
* Created with IntelliJ IDEA.
*
* @author: 风离
* @Date: 2021/07/14/15:37
* @Description:
*/
@Controller
public class IndexController {
public MyCookie myCookie=new MyCookie();

@GetMapping("/") //打开页面直接跳到登录页面
public String login(HttpServletRequest request){
//验证Cookie
Cookie[] cookies=request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
// System.out.println(cookie.getName()+"----"+cookie.getValue());
if (cookie.getName().equals("username")){
if(cookie.getValue().equals(myCookie.getUserName_Cookie()))
{
return "index"; //如果本地Cookie有这个账号记录就直接跳到首页
}
}
}
}
return "login";
}
@PostMapping("/login")
public String main(User user, HttpSession session, Model model, String remember, HttpServletRequest request, HttpServletResponse response) throws Exception {
if(!StringUtils.isEmpty(user.getUsername())&&"fl1906".equals(user.getUsername())&&"rewq4321".equals(user.getPassword())&&!StringUtils.isEmpty(user.getPassword()))
{
System.out.println(remember);
if("remember-me".equals(remember)) // 如果记住密码 添加cookie
{
Cookie cookie1=new Cookie("username", MD5Util.md5Encode(user.getUsername()));
cookie1.setMaxAge(60*60);
response.addCookie(cookie1);
myCookie.setUserName_Cookie(cookie1.getValue());
// Cookie[] cookies=request.getCookies();
// if (cookies != null) {
// for (Cookie cookie : cookies) {
// System.out.println(cookie.getName()+"--->"+cookie.getValue());
// }
//
// }
}
// }else { //删除cookie
// Cookie[] cookies=request.getCookies();
// if (cookies != null) {
// for (int i = 0; i < cookies.length; i++) {
// cookies[i].setMaxAge(0);
// response.addCookie(cookies[i]);
// }
// }
//
// }
session.setAttribute("loginUser",user);
}else {
model.addAttribute("msg","账号密码错误");
return "login";
}
return "redirect:/realLogin"; //防止刷新表单重复提交 无论怎么刷新也只是刷新首页 没有重复提交表单
// return "index";
}
@GetMapping("/realLogin")
public String mainPage(HttpSession session,Model model){
if (session.getAttribute("loginUser") != null) {
return "index"; // 防止直接跳过登录页面到首页
}
model.addAttribute("msg","未登陆哦~~");
return "login";
}
}

前端 代码

引入thymeLeaf模板 <html lang="en" xmlns:th="http://www.thymeleaf.org">

<!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>登陆</title>

<link href="css/style.css" rel="stylesheet">
<!-- 响应式样式 -->
<link href="css/style-responsive.css" rel="stylesheet">

<!-- js IE8支持HTML5元素和媒体查询 IE 兼容脚本 -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
</head>

<body class="login-body">

<div class="container">

<form class="form-signin" action="/qwwqq" method="post" th:action="@{/login}">
<div class="form-signin-heading text-center">
<h1 class="sign-title">登录</h1>
<img src="images/login-logo.png" alt=""/>
</div>
<div class="login-wrap">
<h3 th:text="${msg}" style="color: red"></h3>
<input type="text" name="username" class="form-control" placeholder="用户名" autofocus>
<input type="password" name="password" class="form-control" placeholder="密码">

<button class="btn btn-lg btn-login btn-block" type="submit">
<i class="fa fa-check"></i>
</button>

<div class="registration">
还没有账号?
<a class="" href="registration.html">
去注册
</a>
</div>
<label class="checkbox">
<input type="checkbox" value="remember-me" name="remember"> 记住密码
<span class="pull-right">
<a data-toggle="modal" href="#myModal"> 忘记密码?</a>

</span>
</label>

</div>

<!-- Modal -->
<div aria-hidden="true" aria-labelledby="myModalLabel" role="dialog" tabindex="-1" id="myModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">忘记了密码 ?</h4>
</div>
<div class="modal-body">
<p>输入您的电子邮件地址重新设置您的密码.</p>
<input type="text" name="email" placeholder="邮箱" autocomplete="off" class="form-control placeholder-no-fix">

</div>
<div class="modal-footer">
<button data-dismiss="modal" class="btn btn-default" type="button">取消</button>
<button class="btn btn-primary" type="button">提交</button>
</div>
</div>
</div>
</div>
<!-- modal -->

</form>

</div>



<!-- Placed js at the end of the document so the pages load faster -->

<!-- Placed js at the end of the document so the pages load faster -->
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/modernizr.min.js"></script>

</body>
</html>

thymeleaf 提取公共页面

分析: 由于主页面的侧边栏和头部菜单是每个页面的公共部分 我们无需再重复写代码 可以把这一部分提取出来 名为 common.html 然后把重复的代码 放入这个html中 通过

th:fragment :公共页面抽取标签 ;th:include 和th:replace 来获取公共代码

th:include 为包含的意思 包括你写的div 标签 即 <div>公共代码<div>
th:replace 为替换的意思 不包括你写的div 标签 即 公共代码

无标签传参写法:[[${}]] 实例:[[${session.loginUser.username}]]

common.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="commonHeader">
<meta charset="UTF-8">
<title>公共页面</title>
<!--//th:fragment :公共页面抽取标签 -->
<!--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">

<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="js/html5shiv.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
</head>
<body>

<!-- 左侧菜单栏 -->
<!-- left side start-->
<div th:fragment="CLeft" class="left-side sticky-left-side">

<!--logo and iconic logo start-->
<div class="logo">
<a href="index.html"><img src="images/logo.png" alt=""></a>
</div>

<div class="logo-icon text-center">
<a href="index.html"><img src="images/logo_icon.png" alt=""></a>
</div>
<!--logo and iconic logo end-->


<div class="left-side-inner">

<!-- visible to small devices only -->
<div class="visible-xs hidden-sm hidden-md hidden-lg">
<div class="media logged-user">
<img alt="" src="images/photos/user-avatar.png" class="media-object">
<div class="media-body">
<h4><a href="#">John Doe</a></h4>
<span>"Hello There..."</span>
</div>
</div>

<h5 class="left-nav-title">Account Information</h5>
<ul class="nav nav-pills nav-stacked custom-nav">
<li><a href="#"><i class="fa fa-user"></i> <span>Profile</span></a></li>
<li><a href="#"><i class="fa fa-cog"></i> <span>Settings</span></a></li>
<li><a href="#"><i class="fa fa-sign-out"></i> <span>Sign Out</span></a></li>
</ul>
</div>

<!--sidebar nav start-->
<ul class="nav nav-pills nav-stacked custom-nav">
<li class="menu-list"><a href="index.html"><i class="fa fa-home"></i> <span>Dashboard</span></a>
<ul class="sub-menu-list">
<li><a href="index_alt.html"> Dashboard 1</a></li>
<li><a href="index.html"> Dashboard 2</a></li>
</ul>
</li>
<li class="menu-list"><a href=""><i class="fa fa-laptop"></i> <span>Layouts</span></a>
<ul class="sub-menu-list">
<li ><a href="blank_page.html"> Blank Page</a></li>
<li><a href="boxed_view.html"> Boxed Page</a></li>
<li><a href="leftmenu_collapsed_view.html"> Sidebar Collapsed</a></li>
<li><a href="horizontal_menu.html"> Horizontal Menu</a></li>

</ul>
</li>
<li class="menu-list"><a href=""><i class="fa fa-book"></i> <span>UI Elements</span></a>
<ul class="sub-menu-list">
<li><a href="general.html"> General</a></li>
<li><a href="buttons.html"> Buttons</a></li>
<li><a href="tabs-accordions.html"> Tabs & Accordions</a></li>
<li><a href="typography.html"> Typography</a></li>
<li><a href="slider.html"> Slider</a></li>
<li><a href="panels.html"> Panels</a></li>
<li><a href="widgets.html"> Widgets</a></li>
</ul>
</li>
<li class="menu-list"><a href=""><i class="fa fa-cogs"></i> <span>Components</span></a>
<ul class="sub-menu-list">
<li><a href="grids.html"> Grids</a></li>
<li><a href="gallery.html"> Media Gallery</a></li>
<li><a href="calendar.html"> Calendar</a></li>
<li><a href="tree_view.html"> Tree View</a></li>
<li><a href="nestable.html"> Nestable</a></li>

</ul>
</li>

<li><a href="fontawesome.html"><i class="fa fa-bullhorn"></i> <span>Fontawesome</span></a></li>

<li class="menu-list"><a href=""><i class="fa fa-envelope"></i> <span>Mail</span></a>
<ul class="sub-menu-list">
<li><a href="mail.html"> Inbox</a></li>
<li><a href="mail_compose.html"> Compose Mail</a></li>
<li><a href="mail_view.html"> View Mail</a></li>
</ul>
</li>

<li class="menu-list"><a href=""><i class="fa fa-tasks"></i> <span>Forms</span></a>
<ul class="sub-menu-list">
<li><a href="form_layouts.html"> Form Layouts</a></li>
<li><a href="form_advanced_components.html"> Advanced Components</a></li>
<li><a href="form_wizard.html"> Form Wizards</a></li>
<li><a href="form_validation.html"> Form Validation</a></li>
<li><a href="editors.html"> Editors</a></li>
<li><a href="inline_editors.html"> Inline Editors</a></li>
<li><a href="pickers.html"> Pickers</a></li>
<li><a href="dropzone.html"> Dropzone</a></li>
</ul>
</li>
<li class="menu-list"><a href=""><i class="fa fa-bar-chart-o"></i> <span>Charts</span></a>
<ul class="sub-menu-list">
<li><a href="flot_chart.html"> Flot Charts</a></li>
<li><a href="morris.html"> Morris Charts</a></li>
<li><a href="chartjs.html"> Chartjs</a></li>
<li><a href="c3chart.html"> C3 Charts</a></li>
</ul>
</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 href="/basic_table"> Basic Table</a></li>
<li class="active"><a href="/dynamic_table"> Advanced Table</a></li>
<li><a href="/responsive_table"> Responsive Table</a></li>
<li><a href="/editable_table"> Edit Table</a></li>
</ul>
</li>

<li class="menu-list"><a href="#"><i class="fa fa-map-marker"></i> <span>Maps</span></a>
<ul class="sub-menu-list">
<li><a href="google_map.html"> Google Map</a></li>
<li><a href="vector_map.html"> Vector Map</a></li>
</ul>
</li>
<li class="menu-list"><a href=""><i class="fa fa-file-text"></i> <span>Extra Pages</span></a>
<ul class="sub-menu-list">
<li><a href="profile.html"> Profile</a></li>
<li><a href="invoice.html"> Invoice</a></li>
<li><a href="pricing_table.html"> Pricing Table</a></li>
<li><a href="timeline.html"> Timeline</a></li>
<li><a href="blog_list.html"> Blog List</a></li>
<li><a href="blog_details.html"> Blog Details</a></li>
<li><a href="directory.html"> Directory </a></li>
<li><a href="chat.html"> Chat </a></li>
<li><a href="404.html"> 404 Error</a></li>
<li><a href="500.html"> 500 Error</a></li>
<li><a href="registration.html"> Registration Page</a></li>
<li><a href="lock_screen.html"> Lockscreen </a></li>
</ul>
</li>
<li><a href="login.html"><i class="fa fa-sign-in"></i> <span>Login Page</span></a></li>

</ul>
<!--sidebar nav end-->

</div>
</div>
<!-- left side end-->

<!-- 头部 -->
<!-- header section start-->
<div th:fragment="CHeader" class="header-section">

<!--toggle button start-->
<a class="toggle-btn"><i class="fa fa-bars"></i></a>
<!--toggle button end-->

<!--search start-->
<form class="searchform" action="http://view.jqueryfuns.com/2014/4/10/7_df25ceea231ba5f44f0fc060c943cdae/index.html" method="post">
<input type="text" class="form-control" name="keyword" placeholder="Search here..." />
</form>
<!--search end-->

<!--notification menu start -->
<div class="menu-right">
<ul class="notification-menu">
<li>
<a href="#" class="btn btn-default dropdown-toggle info-number" data-toggle="dropdown">
<i class="fa fa-tasks"></i>
<span class="badge">8</span>
</a>
<div class="dropdown-menu dropdown-menu-head pull-right">
<h5 class="title">You have 8 pending task</h5>
<ul class="dropdown-list user-list">
<li class="new">
<a href="#">
<div class="task-info">
<div>Database update</div>
</div>
<div class="progress progress-striped">
<div style="width: 40%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="40" role="progressbar" class="progress-bar progress-bar-warning">
<span class="">40%</span>
</div>
</div>
</a>
</li>
<li class="new">
<a href="#">
<div class="task-info">
<div>Dashboard done</div>
</div>
<div class="progress progress-striped">
<div style="width: 90%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="90" role="progressbar" class="progress-bar progress-bar-success">
<span class="">90%</span>
</div>
</div>
</a>
</li>
<li>
<a href="#">
<div class="task-info">
<div>Web Development</div>
</div>
<div class="progress progress-striped">
<div style="width: 66%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="66" role="progressbar" class="progress-bar progress-bar-info">
<span class="">66% </span>
</div>
</div>
</a>
</li>
<li>
<a href="#">
<div class="task-info">
<div>Mobile App</div>
</div>
<div class="progress progress-striped">
<div style="width: 33%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="33" role="progressbar" class="progress-bar progress-bar-danger">
<span class="">33% </span>
</div>
</div>
</a>
</li>
<li>
<a href="#">
<div class="task-info">
<div>Issues fixed</div>
</div>
<div class="progress progress-striped">
<div style="width: 80%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="80" role="progressbar" class="progress-bar">
<span class="">80% </span>
</div>
</div>
</a>
</li>
<li class="new"><a href="">See All Pending Task</a></li>
</ul>
</div>
</li>
<li>
<a href="#" class="btn btn-default dropdown-toggle info-number" data-toggle="dropdown">
<i class="fa fa-envelope-o"></i>
<span class="badge">5</span>
</a>
<div class="dropdown-menu dropdown-menu-head pull-right">
<h5 class="title">You have 5 Mails </h5>
<ul class="dropdown-list normal-list">
<li class="new">
<a href="">
<span class="thumb"><img src="images/photos/user1.png" alt="" /></span>
<span class="desc">
<span class="name">John Doe <span class="badge badge-success">new</span></span>
<span class="msg">Lorem ipsum dolor sit amet...</span>
</span>
</a>
</li>
<li>
<a href="">
<span class="thumb"><img src="images/photos/user2.png" alt="" /></span>
<span class="desc">
<span class="name">Jonathan Smith</span>
<span class="msg">Lorem ipsum dolor sit amet...</span>
</span>
</a>
</li>
<li>
<a href="">
<span class="thumb"><img src="images/photos/user3.png" alt="" /></span>
<span class="desc">
<span class="name">Jane Doe</span>
<span class="msg">Lorem ipsum dolor sit amet...</span>
</span>
</a>
</li>
<li>
<a href="">
<span class="thumb"><img src="images/photos/user4.png" alt="" /></span>
<span class="desc">
<span class="name">Mark Henry</span>
<span class="msg">Lorem ipsum dolor sit amet...</span>
</span>
</a>
</li>
<li>
<a href="">
<span class="thumb"><img src="images/photos/user5.png" alt="" /></span>
<span class="desc">
<span class="name">Jim Doe</span>
<span class="msg">Lorem ipsum dolor sit amet...</span>
</span>
</a>
</li>
<li class="new"><a href="">Read All Mails</a></li>
</ul>
</div>
</li>
<li>
<a href="#" class="btn btn-default dropdown-toggle info-number" data-toggle="dropdown">
<i class="fa fa-bell-o"></i>
<span class="badge">4</span>
</a>
<div class="dropdown-menu dropdown-menu-head pull-right">
<h5 class="title">Notifications</h5>
<ul class="dropdown-list normal-list">
<li class="new">
<a href="">
<span class="label label-danger"><i class="fa fa-bolt"></i></span>
<span class="name">Server #1 overloaded. </span>
<em class="small">34 mins</em>
</a>
</li>
<li class="new">
<a href="">
<span class="label label-danger"><i class="fa fa-bolt"></i></span>
<span class="name">Server #3 overloaded. </span>
<em class="small">1 hrs</em>
</a>
</li>
<li class="new">
<a href="">
<span class="label label-danger"><i class="fa fa-bolt"></i></span>
<span class="name">Server #5 overloaded. </span>
<em class="small">4 hrs</em>
</a>
</li>
<li class="new">
<a href="">
<span class="label label-danger"><i class="fa fa-bolt"></i></span>
<span class="name">Server #31 overloaded. </span>
<em class="small">4 hrs</em>
</a>
</li>
<li class="new"><a href="">See All Notifications</a></li>
</ul>
</div>
</li>
<li>
<a href="#" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<img src="images/photos/user-avatar.png" alt="" />
John Doe
<span class="caret"></span>
</a>
<ul class="dropdown-menu dropdown-menu-usermenu pull-right">
<li><a href="#"><i class="fa fa-user"></i> Profile</a></li>
<li><a href="#"><i class="fa fa-cog"></i> Settings</a></li>
<li><a href="#"><i class="fa fa-sign-out"></i> Log Out</a></li>
</ul>
</li>

</ul>
</div>
<!--notification menu end -->

</div>
<!-- header section end-->

<div th:fragment="commonScript">
<!-- Placed js at the end of the document so the pages load faster -->
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/jquery-ui-1.9.2.custom.min.js"></script>
<script src="js/jquery-migrate-1.2.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/modernizr.min.js"></script>
<script src="js/jquery.nicescroll.js"></script>
<!--common scripts for all pages-->
<script src="js/scripts.js"></script>
</div>

</body>
</html>

引用公共页面common.html

<div th:replace="common ::CHeader"> </div> 公共头部菜单

<div th:replace="common ::CLeft"/> 公共侧边栏

<link th:include="common :: commonHeader"> 公共头文件css等

<div th:include="common :: commonScript"/> 公共Script