当前位置:网站首页>第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>项目测试·
点击张三

点击退出

点击确定

成功返回主页面
边栏推荐
- [source code interpretation] | source code interpretation of livelistenerbus
- Notes on installing MySQL in centos7
- 大笨钟(Lua)
- The mail server is listed in the blacklist. How to unblock it quickly?
- centos7安装mysql笔记
- LeetCode 1477. Find two subarrays with sum as the target value and no overlap
- LeetCode 152. Product maximum subarray daily question
- Devops' operational and commercial benefits Guide
- 麒麟信安携异构融合云金融信创解决方案亮相第十五届湖南地区金融科技交流会
- Lex & yacc of Pisa proxy SQL parsing
猜你喜欢

MRS离线数据分析:通过Flink作业处理OBS数据

麒麟信安中标国网新一代调度项目!

麒麟信安携异构融合云金融信创解决方案亮相第十五届湖南地区金融科技交流会

Seaborn data visualization

【信息安全法律法規】複習篇

PLC: automatically correct the data set noise, wash the data set | ICLR 2021 spotlight

DevOps 的运营和商业利益指南

Skimage learning (2) -- RGB to grayscale, RGB to HSV, histogram matching

【可信计算】第十三次课:TPM扩展授权与密钥管理

QML beginner
随机推荐
[fan Tan] after the arrival of Web3.0, where should testers go? (ten predictions and suggestions)
测试用例管理工具推荐
Seaborn数据可视化
Rpcms method of obtaining articles under the specified classification
Sator launched Web3 game "satorspace" and launched hoobi
AI来搞财富分配比人更公平?来自DeepMind的多人博弈游戏研究
DNS series (I): why does the updated DNS record not take effect?
Blue Bridge Cup final XOR conversion 100 points
A tour of grpc:03 - proto serialization / deserialization
Solidity 开发环境搭建
LeetCode 515(C#)
如何在博客中添加Aplayer音乐播放器
Skimage learning (3) -- adapt the gray filter to RGB images, separate colors by immunohistochemical staining, and filter the maximum value of the region
麒麟信安携异构融合云金融信创解决方案亮相第十五届湖南地区金融科技交流会
到底有多二(Lua)
L1-027 出租(Lua)
LeetCode1051(C#)
On Apache Doris Fe processing query SQL source code analysis
Test case management tool recommendation
[Seaborn] combination chart: pairplot and jointplot