跳转欢迎页
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script type="text/javascript">
document.location.href = "settings/user/toLogin.do";//这里通过请求验证是否登录还是直接进入工作台首页
</script>
</body>
</html>
在UserController 中接收请求,验证是否存在Cookie可以直接登录,若不存在则跳转到login登录页面
UserController .java
@Controller
@RequestMapping("/settings/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/toLogin.do")
public String toLogin(HttpServletRequest request) {
//验证用户是否执行过了十天免登陆操作
Cookie[] cookies = request.getCookies();
String loginAct = null;
String loginPwd = null;
if(cookies!=null && cookies.length>0){
for(Cookie cookie : cookies){
String name = cookie.getName();
if("loginAct".equals(name)){
loginAct = cookie.getValue();
continue;
}
if("loginPwd".equals(name)){
loginPwd = cookie.getValue();
}
}
}
if(loginAct!=null && loginPwd!=null){
//说明已经做过十天免登陆了
//通过账号密码重新做登录操作
String ip = request.getRemoteAddr();
try {
User user = userService.login(loginAct, loginPwd, ip);
request.getSession().setAttribute("user", user);
//以上我们是在判断了十天免登陆操作后,自动的为用户做了登录操作
//需要直接跳转到欢迎页
return "redirect:/workbench/toIndex.do";
} catch (LoginException e) {
e.printStackTrace();
return "/login";
}
}else{
//说明并没有从cookie中取得我们所需要的账号和密码
//没有做过十天免登陆
//访问登录页
return "/login";
}
}
}
登录页面发送请求,可勾选十天免登陆
- 在login登录页面通过ajax验证数据库是否存在账号密码,若不存在,则显示错误信息;若存在,则发送跳转工作台首页的请求
- 请求参数需要包括十天免登陆,在后台判断是否勾选,决定是否设置
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<meta charset="UTF-8">
<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>
$(function () {
//在页面加载完毕后,使得用户名文本框自动取得焦点
$("#loginAct").focus();
//为登录按钮绑定事件,执行登录操作
$("#submitBtn").click(function () {
login();
})
//为当前窗口绑定敲键盘事件,如果敲的是回车键,则执行登录操作
/*
我们可以通过event参数来取得所敲的键盘的码值
如果码值为13,说明敲的是回车键
*/
$(window).keydown(function (event) {
var code = event.keyCode;
//如果码值为13,说明是回车键
if(code==13){
//执行登录操作
//alert("登录操作2");
login();
}
})
})
/*
注意:
项目开发中,我们自定义的function方法,一定要写在$(function(){})的体外
*/
function login() {
/*
关于jquery的存取值问题
主要是针对于表单元素的value属性值的存取值操作
相当于是原生js的 document.getElementById("").value
val():取值
val(值):赋值
主要是针对于标签对中的内容的存取值操作(操作的是可带元素的文本)
相当于是原生js的 document.getElementById("").innerHTML;
html():取值
html("<font color='red'>hello world!!!</font>"):赋值
主要是针对于标签对中的内容的存取值操作(操作的是纯文本)
text():取值
text("hello world!!!"):赋值
*/
//验证账号密码是否为空
//取得账号密码
//取出内容左右空格:$.trim(内容)
var loginAct = $.trim($("#loginAct").val());
var loginPwd = $.trim($("#loginPwd").val());
if(loginAct==""||loginPwd==""){
$("#msg").html("账号密码不能为空");
//及时终止掉方法
return false;
}
var flag = "";
if($("#flag").prop("checked")){
flag = "a";
}
//验证账号密码是否正确
$.ajax({
url : "settings/user/login.do", //请求路径
data : {
"loginAct" : loginAct,
"loginPwd" : loginPwd,
"flag" : flag
}, //请求参数
type : "post", //请求方式
dataType : "json", //接收响应信息的方式
success : function (data) { //回调函数 data:从后台响应回来的信息
/*
data
{"success":true/false,"msg":?}
*/
if(data.success){
//登录成功
//跳转到欢迎页
//我们以下以超链接的形式,不可能直接访问到WEB-INF下的资源
//WEB-INF下的资源只有一种方式能够访问到:请求转发
window.location.href = "workbench/toIndex.do";
}else{
//登录失败
//需要在<span id="msg"></span>的标签对中,局部刷新错误信息
$("#msg").html(data.msg);
}
}
})
}
</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;">©2019 动力节点</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" type="text" placeholder="用户名" autocomplete="off" id="loginAct">
</div>
<div style="width: 350px; position: relative;top: 20px;">
<input class="form-control" type="password" placeholder="密码" id="loginPwd">
</div>
<div class="checkbox" style="position: relative;top: 30px; left: 10px;">
<label>
<input type="checkbox" id="flag"> 十天内免登录
</label>
<span id="msg" style="color: red"></span>
</div>
<!--
注意:
此处button按钮,类型必须设置为button,否则会发出传统请求,提交form表单
-->
<button type="button" id="submitBtn" class="btn btn-primary btn-lg btn-block" style="width: 350px; position: relative;top: 45px;">登录</button>
</div>
</form>
</div>
</div>
</body>
</html>
在UserController 中进行登录的账号密码判断,同时判断是否设置十天免登陆
UserController.java
@Controller
@RequestMapping("/settings/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login.do")
@ResponseBody
public Map<String,Object> login(String loginAct, String loginPwd, String flag, HttpServletRequest request, HttpServletResponse response)throws LoginException {
//取得浏览器端的ip地址
/*
注意:
如果我们自己访问自己,使用的不是一个正常的ip地址(例如使用的是localhost)
那么通过getRemoteAddr方法为我们返回的就是一堆0000加一个1 0:0:0:0..1
取得的并不是一个有效的ip地址,这不是我们想要的
我们可以使用自己本机的ip地址进行访问,也可以使用127.0.0.1来代替本机的ip地址
*/
String ip = request.getRemoteAddr();
loginPwd = MD5Util.getMD5(loginPwd);
User user = userService.login(loginAct,loginPwd,ip);
request.getSession().setAttribute("user", user);
//通过flag值是否为a,来判断是否需要处理"十天免登陆"操作
/*
使用cookie来对"十天免登陆"功能进行操作
流程:
需要创建两个cookie对象,一个用来保存账号,一个用来保存密码(存密文即可)
对这两个cookie对象进行时间的设置 10天
对这两个cookie对象进行访问路径的设置
对这两个cookie进行响应添加
*/
if("a".equals(flag)){
Cookie cookie1 = new Cookie("loginAct", loginAct);
Cookie cookie2 = new Cookie("loginPwd", loginPwd);
cookie1.setMaxAge(60*60*24*10);
cookie2.setMaxAge(60*60*24*10);
cookie1.setPath("/");
cookie2.setPath("/");
response.addCookie(cookie1);
response.addCookie(cookie2);
}
/*
登录成功
我们应该为前端提供的信息是
{"success":true}
*/
/*Map<String,Object> map = new HashMap<>();
map.put("success", true);*/
return HandleFlag.successTrue();
}
@RequestMapping("/logout.do")
public String logout(HttpSession session,HttpServletResponse response){
//将session对象销毁
session.invalidate();
/*
Cookie类型并没有为我们提供直接销毁的方法
所以我们只能使用新的cookie来代替老的cookie方法将老的cookie对象进行销毁的操作
新cookie将保存时间设置为0,将相当于是cookie的销毁操作了
*/
Cookie cookie1 = new Cookie("loginAct",null);
Cookie cookie2 = new Cookie("loginPwd",null);
cookie1.setPath("/");
cookie2.setPath("/");
cookie1.setMaxAge(0);
cookie2.setMaxAge(0);
response.addCookie(cookie1);
response.addCookie(cookie2);
return "/login";
}
}
在UserServiceImpl 这里进行业务操作,与数据库的账号密码对比,同时对失效时间,锁定状态,IP地址进行判断
UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public User login(String loginAct, String loginPwd, String ip)throws LoginException {
Map<String,String> map = new HashMap<>();
map.put("loginAct", loginAct);
map.put("loginPwd", loginPwd);
//验证账号密码是否正确,通过dao层执行sql语句来验证,为我们返回User
User user = userDao.login(map);
/*
判断user是否为null
*/
//user==null说明账号密码不正确
if(user==null){
throw new LoginException("账号密码错误");
}
//如果程序能够顺利的走到该行,说明上面没有抛异常,说明账号密码是正确的
//需要继续向下验证
//验证失效时间
String expireTime = user.getExpireTime();
if(expireTime.compareTo(DateTimeUtil.getSysTime())<0){
throw new LoginException("账号已失效");
}
//验证锁定状态
String lockState = user.getLockState();
if(lockState!=null){
if(Const.LOCKSTATE_CLOSE.equals(lockState)){
throw new LoginException("账号已锁定");
}
}
//验证ip地址
String allowIps = user.getAllowIps();
if(allowIps!=null){
if(!allowIps.contains(ip)){
throw new LoginException("ip地址受限");
}
}
/*
如果程序能够走到该行,说明上面4处抛异常,都没有执行
登录成功
为控制器返回user对象
*/
return user;
}
}
如果存在cookie,执行这一步,跳转工作台请求
@Controller
public class WorkbenchController {
@RequestMapping("/workbench/toIndex.do")
public String toIndex(){
/*
请求转发到/WEB-INF/jsp/workbench/index.jsp
(1)使用HttpServletRequest
(2)使用ModelAndView
以上这两种形式在做请求转发的同时,还可以将数据保存到request域对象中
但是对于我们现在的需求,就是做个转发就可以了,不需要在request域对象中打包数据
所以我们直接使用SpringMVC已经配置好的视图解析器就可以了
如果使用视图解析器,我们的返回值需要设置为String类型
*/
return "/workbench/index";
}
@RequestMapping("/workbench/main/toIndex.do")
public String mainToIndex(){
return "/workbench/main/index";
}
}
拦截器
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/*
由此拦截器判断是否已经登录过
如果登录过,则返回true(将请求放行)
如果没有登录过,则回到登录页
可以通过session域对象中有没有user对象来进行判断
*/
User user = (User)request.getSession().getAttribute("user");
if(user==null){
//说明没有登录过
throw new InterceptorException();
}
return true;
}
退出账号
UserController .java
@Controller
@RequestMapping("/settings/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/logout.do")
public String logout(HttpSession session,HttpServletResponse response){
//将session对象销毁
session.invalidate();
/*
Cookie类型并没有为我们提供直接销毁的方法
所以我们只能使用新的cookie来代替老的cookie方法将老的cookie对象进行销毁的操作
新cookie将保存时间设置为0,将相当于是cookie的销毁操作了
*/
Cookie cookie1 = new Cookie("loginAct",null);
Cookie cookie2 = new Cookie("loginPwd",null);
cookie1.setPath("/");
cookie2.setPath("/");
cookie1.setMaxAge(0);
cookie2.setMaxAge(0);
response.addCookie(cookie1);
response.addCookie(cookie2);
return "/login";
}
}