当前位置:网站首页>第3章业务功能开发(安全退出)
第3章业务功能开发(安全退出)
2022-07-07 15:39:00 【做一道光】
客户需求
用户在任意的业务页面,点击"退出"按钮,弹出确认退出的模态窗口;用户在确认退出的模态窗口,点击"确定"按钮,完成安全退出的功能.
*安全退出,清空cookie,销毁session
*退出完成之后,跳转到首页
1.首先根据客户需求画出UML时序图。

2.在工作台首页面点击退出登录

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<meta charset="UTF-8">
<base href="<%=basePath%>">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
//页面加载完毕
$(function(){
//导航中所有文本颜色为黑色
$(".liClass > a").css("color" , "black");
//默认选中导航菜单中的第一个菜单项
$(".liClass:first").addClass("active");
//第一个菜单项的文字变成白色
$(".liClass:first > a").css("color" , "white");
//给所有的菜单项注册鼠标单击事件
$(".liClass").click(function(){
//移除所有菜单项的激活状态
$(".liClass").removeClass("active");
//导航中所有文本颜色为黑色
$(".liClass > a").css("color" , "black");
//当前项目被选中
$(this).addClass("active");
//当前项目颜色变成白色
$(this).children("a").css("color","white");
});
window.open("main/index.html","workareaFrame");
//给确定按钮添加单击事件
$("#logoutBtn").click(function () {
//发送同步请求
window.location.href="settings/qx/user/logout.do";
});
});
</script>
</head>
<body>
<!-- 我的资料 -->
<div class="modal fade" id="myInformation" role="dialog">
<div class="modal-dialog" role="document" style="width: 30%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">我的资料</h4>
</div>
<div class="modal-body">
<div style="position: relative; left: 40px;">
姓名:<b>张三</b><br><br>
登录帐号:<b>zhangsan</b><br><br>
组织机构:<b>1005,市场部,二级部门</b><br><br>
邮箱:<b>[email protected]</b><br><br>
失效时间:<b>2017-02-14 10:10:10</b><br><br>
允许访问IP:<b>127.0.0.1,192.168.100.2</b>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
<!-- 修改密码的模态窗口 -->
<div class="modal fade" id="editPwdModal" role="dialog">
<div class="modal-dialog" role="document" style="width: 70%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">修改密码</h4>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="oldPwd" class="col-sm-2 control-label">原密码</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="oldPwd" style="width: 200%;">
</div>
</div>
<div class="form-group">
<label for="newPwd" class="col-sm-2 control-label">新密码</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="newPwd" style="width: 200%;">
</div>
</div>
<div class="form-group">
<label for="confirmPwd" class="col-sm-2 control-label">确认密码</label>
<div class="col-sm-10" style="width: 300px;">
<input type="text" class="form-control" id="confirmPwd" style="width: 200%;">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" onclick="window.location.href='login.html';">更新</button>
</div>
</div>
</div>
</div>
<!-- 退出系统的模态窗口 -->
<div class="modal fade" id="exitModal" role="dialog">
<div class="modal-dialog" role="document" style="width: 30%;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">离开</h4>
</div>
<div class="modal-body">
<p>您确定要退出系统吗?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" id="logoutBtn">确定</button>
</div>
</div>
</div>
</div>
<!-- 顶部 -->
<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">客户关系管理系统(LJL)</span></div>
<div style="position: absolute; top: 15px; right: 15px;">
<ul>
<li class="dropdown user-dropdown">
<a href="javascript:void(0)" style="text-decoration: none; color: white;" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-user"></span>${sessionScope.sessionUser.name}<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="settings/index.html"><span class="glyphicon glyphicon-wrench"></span> 系统设置</a></li>
<li><a href="javascript:void(0)" data-toggle="modal" data-target="#myInformation"><span class="glyphicon glyphicon-file"></span> 我的资料</a></li>
<li><a href="javascript:void(0)" data-toggle="modal" data-target="#editPwdModal"><span class="glyphicon glyphicon-edit"></span> 修改密码</a></li>
<li><a href="javascript:void(0);" data-toggle="modal" data-target="#exitModal"><span class="glyphicon glyphicon-off"></span> 退出</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!-- 中间 -->
<div id="center" style="position: absolute;top: 50px; bottom: 30px; left: 0px; right: 0px;">
<!-- 导航 -->
<div id="navigation" style="left: 0px; width: 18%; position: relative; height: 100%; overflow:auto;">
<ul id="no1" class="nav nav-pills nav-stacked">
<li class="liClass"><a href="main/index.html" target="workareaFrame"><span class="glyphicon glyphicon-home"></span> 工作台</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-tag"></span> 动态</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-time"></span> 审批</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-user"></span> 客户公海</a></li>
<li class="liClass"><a href="activity/index.html" target="workareaFrame"><span class="glyphicon glyphicon-play-circle"></span> 市场活动</a></li>
<li class="liClass"><a href="clue/index.html" target="workareaFrame"><span class="glyphicon glyphicon-search"></span> 线索(潜在客户)</a></li>
<li class="liClass"><a href="customer/index.html" target="workareaFrame"><span class="glyphicon glyphicon-user"></span> 客户</a></li>
<li class="liClass"><a href="contacts/index.html" target="workareaFrame"><span class="glyphicon glyphicon-earphone"></span> 联系人</a></li>
<li class="liClass"><a href="transaction/index.html" target="workareaFrame"><span class="glyphicon glyphicon-usd"></span> 交易(商机)</a></li>
<li class="liClass"><a href="visit/index.html" target="workareaFrame"><span class="glyphicon glyphicon-phone-alt"></span> 售后回访</a></li>
<li class="liClass">
<a href="#no2" class="collapsed" data-toggle="collapse"><span class="glyphicon glyphicon-stats"></span> 统计图表</a>
<ul id="no2" class="nav nav-pills nav-stacked collapse">
<li class="liClass"><a href="chart/activity/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 市场活动统计图表</a></li>
<li class="liClass"><a href="chart/clue/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 线索统计图表</a></li>
<li class="liClass"><a href="chart/customerAndContacts/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 客户和联系人统计图表</a></li>
<li class="liClass"><a href="chart/transaction/index.html" target="workareaFrame"> <span class="glyphicon glyphicon-chevron-right"></span> 交易统计图表</a></li>
</ul>
</li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-file"></span> 报表</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-shopping-cart"></span> 销售订单</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-send"></span> 发货单</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-earphone"></span> 跟进</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-leaf"></span> 产品</a></li>
<li class="liClass"><a href="javascript:void(0);" target="workareaFrame"><span class="glyphicon glyphicon-usd"></span> 报价</a></li>
</ul>
<!-- 分割线 -->
<div id="divider1" style="position: absolute; top : 0px; right: 0px; width: 1px; height: 100% ; background-color: #B3B3B3;"></div>
</div>
<!-- 工作区 -->
<div id="workarea" style="position: absolute; top : 0px; left: 18%; width: 82%; height: 100%;">
<iframe style="border-width: 0px; width: 100%; height: 100%;" name="workareaFrame"></iframe>
</div>
</div>
<div id="divider2" style="height: 1px; width: 100%; position: absolute;bottom: 30px; background-color: #B3B3B3;"></div>
<!-- 底部 -->
<div id="down" style="height: 30px; width: 100%; position: absolute;bottom: 0px;"></div>
</body>
</html>3.跳转到UserController类中的logout方法,该方法返回到项目首页

4.返回到项目首页的index.jsp页面

5.项目首页跳转到UserController类,通过该类中的toLogin方法跳转到登录页面

package com.it.crm.settings.web.controller;
import com.it.crm.commons.contants.Contants;
import com.it.crm.commons.entity.ReturnObject;
import com.it.crm.commons.utils.DateUtils;
import com.it.crm.settings.entity.User;
import com.it.crm.settings.service.UserService;
import com.sun.deploy.net.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/settings/qx/user/toLogin.do")
public String toLogin(){
return "settings/qx/user/login";
}
@RequestMapping(value = "/settings/qx/user/login.do")
@ResponseBody
public Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpServletResponse response, HttpSession session){
//封装参数
Map<String,Object> map=new HashMap<>();
map.put("loginAct",loginAct);
map.put("loginPwd",loginPwd);
map.put("isRemPwd",isRemPwd);
//调用service层方法,查询用户
User user = userService.queryUserByActAndPwd(map);
//根据查询结果生成响应信息
ReturnObject returnObject=new ReturnObject();
if (user==null){
//登录失败,用户名或密码错误
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("用户名或密码错误");
}else {//进一步判断账号是否合法
if (DateUtils.formateDateTime(new Date()).compareTo(user.getExpireTime())>0){
//登录失败,账号已过期
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("账号已经过期");
}else if ("0".equals(user.getLockState())){
//登录失败,状态被锁定
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("状态被锁定");
}else if (!user.getAllowIps().contains(request.getRemoteAddr())){
//登录失败,ip受限
returnObject.setCode(Contants.RETURN_OBJECT_CODE_FAIL);
returnObject.setMessage("ip受限");
}else{
//登录成功
returnObject.setCode(Contants.RETURN_OBJECT_CODE_SUCCESS);
//把user保存到session中
session.setAttribute(Contants.SESSION_USER,user);
//如果需要记住密码,则往外写cookie
if("true".equals(isRemPwd)){
Cookie loginAct1 = new Cookie("loginAct", user.getLoginAct());
loginAct1.setMaxAge(60*60*24*10);
response.addCookie(loginAct1);
Cookie loginPwd1 = new Cookie("loginPwd", user.getLoginPwd());
loginPwd1.setMaxAge(60*60*24*10);
response.addCookie(loginPwd1);
}else{
//把没有过期的cookie删除
Cookie c1=new Cookie("loginAct","1");
c1.setMaxAge(0);
response.addCookie(c1);
Cookie c2=new Cookie("loginPwd","2");
c2.setMaxAge(0);
response.addCookie(c2);
}
}
}
return returnObject;
}
@RequestMapping(value = "/settings/qx/user/logout.do")
public String logout(HttpServletResponse response,HttpSession session){
//清空cookie
Cookie c1=new Cookie("loginAct","1");
c1.setMaxAge(0);
response.addCookie(c1);
Cookie c2=new Cookie("loginPwd","2");
c2.setMaxAge(0);
response.addCookie(c2);
//销毁session
session.invalidate();
//跳转到首页
return "redirect:/";
}
}
6.登录页面login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core_1_1" %>
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<meta charset="UTF-8">
<base href="<%=basePath%>">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function () {
//给整个浏览器窗口添加键盘按下事件
$(window).keydown(function (event) {
//如果按的是回车键,则提交登录请求
if (event.keyCode==13){
$("#loginBtn").click();
}
})
//给登录按钮添加单击事件
$("#loginBtn").click(function () {
//收集参数
var loginAct=$.trim($("#loginAct").val());
var loginPwd=$.trim($("#loginPwd").val());
var isRemPwd=$("#isRemPwd").prop("checked");
//表单验证
if (loginAct==""){
alert("用户名不能为空!");
return;
}if (loginPwd==""){
alert("密码不能为空!");
return;
}
//点击登录后显示正在验证
$("#msg").html("正在努力验证中。。。")
//发送请求
$.ajax({
url:'settings/qx/user/login.do',
data:{
loginAct:loginAct,
loginPwd:loginPwd,
isRemPwd:isRemPwd
},
type:'post',
dataType:'json',
success:function (data) {
if (data.code=="1"){
//登录成功,跳转到业务的主页面
window.location.href="workbench/index.do";
}else {
//登录失败,显示提示信息
$("#msg").html(data.message);
}
}
});
});
});
</script>
</head>
<body>
<div style="position: absolute; top: 0px; left: 0px; width: 60%;">
<img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;">
</div>
<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM <span style="font-size: 12px;">客户关系管理系统</span></div>
</div>
<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
<div style="position: absolute; top: 0px; right: 60px;">
<div class="page-header">
<h1>登录</h1>
</div>
<form action="workbench/index.html" class="form-horizontal" role="form">
<div class="form-group form-group-lg">
<div style="width: 350px;">
<input class="form-control" id="loginAct" type="text" value="${cookie.loginAct.value}" placeholder="用户名">
</div>
<div style="width: 350px; position: relative;top: 20px;">
<input class="form-control" id="loginPwd" type="password" value="${cookie.loginPwd.value}" placeholder="密码">
</div>
<div class="checkbox" style="position: relative;top: 30px; left: 10px;">
<label>
<c:if test="${not empty cookie.loginAct and not empty cookie.loginPwd}">
<input type="checkbox" id="isRemPwd" checked/>
</c:if>
<c:if test="${empty cookie.loginAct and empty cookie.loginPwd}">
<input type="checkbox" id="isRemPwd">
</c:if>
十天内免登录
</label>
<span id="msg" style="color: red;"></span>
</div>
<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block" style="width: 350px; position: relative;top: 45px;">登录</button>
</div>
</form>
</div>
</div>
</body>
</html>7. webapp的目录结构
8.applicationContext-mvc.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- dispatcherServlet截获所有URL请求 -->
<mvc:default-servlet-handler />
<!-- 组件扫描器:spring mvc 扫描包下的controller -->
<context:component-scan base-package="com.it.crm.web.controller"/>
<context:component-scan base-package="com.it.crm.settings.web.controller"/>
<context:component-scan base-package="com.it.crm.workbench.web.controller"/>
<!-- 配置注解驱动 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置文件上传解析器 id:必须是multipartResolver-->
<!--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="#{1024*1024*80}"/>
<property name="defaultEncoding" value="utf-8"/>
</bean>-->
</beans>项目测试·
点击张三

点击退出

点击确定

成功返回主页面
边栏推荐
- [video / audio data processing] Shanghai daoning brings you elecard download, trial and tutorial
- 管理VDI的几个最佳实践
- LeetCode1051(C#)
- 自定义View必备知识,Android研发岗必问30+道高级面试题
- 99%的人都不知道|私有化部署还永久免费的即时通讯软件!
- Is AI more fair than people in the distribution of wealth? Research on multiplayer game from deepmind
- 网络攻防复习篇
- 【网络攻防原理与技术】第6章:特洛伊木马
- LeetCode 1981. Minimize the difference between the target value and the selected element one question per day
- L1-027 出租(Lua)
猜你喜欢

Lex & yacc of Pisa proxy SQL parsing

Linux 安装mysql8.X超详细图文教程
![[video / audio data processing] Shanghai daoning brings you elecard download, trial and tutorial](/img/14/4e7ebfb1ed5b99f8377af9d17d2177.jpg)
[video / audio data processing] Shanghai daoning brings you elecard download, trial and tutorial

Mrs offline data analysis: process OBS data through Flink job

Skimage learning (3) -- gamma and log contrast adjustment, histogram equalization, coloring gray images

Seaborn数据可视化

Several best practices for managing VDI

redis主从、哨兵主备切换搭建一步一步图解实现

With the latest Alibaba P7 technology system, mom doesn't have to worry about me looking for a job anymore

【视频/音频数据处理】上海道宁为您带来Elecard下载、试用、教程
随机推荐
The server is completely broken and cannot be repaired. How to use backup to restore it into a virtual machine without damage?
Skimage learning (2) -- RGB to grayscale, RGB to HSV, histogram matching
Devops' operational and commercial benefits Guide
LeetCode 1043. Separate the array to get the maximum and daily questions
[Seaborn] implementation of combined charts and multi subgraphs
99% of users often make mistakes in power Bi cloud reports
策略模式 - Unity
With the latest Alibaba P7 technology system, mom doesn't have to worry about me looking for a job anymore
麒麟信安操作系统衍生产品解决方案 | 存储多路径管理系统,有效提高数据传输可靠性
麒麟信安加入宁夏商用密码协会
QT picture background color pixel processing method
鲲鹏开发者峰会2022 | 麒麟信安携手鲲鹏共筑计算产业新生态
99% 用户在 Power BI 云端报表常犯错误
Lex & yacc of Pisa proxy SQL parsing
让保险更“保险”!麒麟信安一云多芯云桌面中标中国人寿, 助力金融保险信息技术创新发展
Flask搭建api服务
LeetCode 152. Product maximum subarray daily question
L1-025 正整数A+B(Lua)
LeetCode刷题day49
Blue Bridge Cup final XOR conversion 100 points