这个完整案例只用简单的 Jsp + Ajax + Servlet来完成。
一、登录
略过页面简单的表单验证,直接进入LoginServlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取表单内容
String userName = request.getParameter("usn");
String pwd = request.getParameter("pwd");
String remember = request.getParameter("remember");
//获取当前会话的session
HttpSession session = request.getSession();
//执行doLogin并返回登录信息是否正确的结果
boolean res = userinfobiz.doLogin(userName, pwd);
if (res) {
//结果为真,通过getUserByname方法获取用户信息
UserInfo user = userinfodao.getUserByName(userName);
//把用户信息存储到session中
session.setAttribute("userName", userName);
session.setAttribute("id", user.getId());
session.setAttribute("email", user.getEmail());
session.setAttribute("state", user.getState());
session.setAttribute("headimageurl", user.getHeadimageurl());
session.setAttribute("nickname", user.getNickname());
session.setAttribute("systemtime", user.getSystemtime());
//给session设置一个自定义变量,代表已经登录了
session.setAttribute("loginstate", "userhavinglogin");
//新建一个name叫做"SINSESSION"的cookie并把用户ID存到value中
Cookie cookie = new Cookie("SINSESSION",user.getId());
//设置作用域,这里设置为根目录以下所有
cookie.setPath("/");
//验证表单获得的参数,如果为真设置cookie生命周期为一周,如果为假设置为1天
if("ture".equals(remember)) {
cookie.setMaxAge(7*24*60*60);
}else{
cookie.setMaxAge(24*60*60);
}
//将设置好的cookie保存到客户端的浏览器
response.addCookie(cookie);
System.out.println("cookie.age: " + cookie.getMaxAge());
System.out.println("cookie.name: " + cookie.getName());
System.out.println("cookie.value: " + cookie.getValue());
//判断用户是否为管理员
String adminname = "sintemple";
if (userName.equals(adminname)) {
request.getRequestDispatcher("/page/manage/admin.jsp").forward(request, response);
} else {
RequestDispatcher rd = request.getRequestDispatcher("/page/main/logsuc.jsp");
rd.forward(request, response);
}
} else {
session.invalidate();
response.sendRedirect("/page/main/logero.jsp");
}
}
二、登录后页面回显用户信息,这里是Ajax载入的Jsp模板
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!-- 如果用户昵称为空显示此段 -->
<c:if test="${sessionScope.nickname == null}">
<li class="nav-item">
<a href="/page/main/login.jsp" style="color: white; font-size: 2em;">
<i class="mdi mdi-account-circle"></i>
</a>
</li>
<!-- 如果用户昵称不为空显示此段 -->
</c:if>
<c:if test="${sessionScope.nickname != null}">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-muted waves-effect waves-dark p-0"
href="" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false"><img src="${sessionScope.headimageurl}"
alt="user" class="profile-pic" /></a>
<div class="dropdown-menu dropdown-menu-right scale-up">
<ul class="dropdown-user">
<li>
<div class="dw-user-box">
<div class="u-img">
<img src="${sessionScope.headimageurl}" alt="user">
</div>
<div class="u-text">
<h4 class="m-b-10">${sessionScope.nickname}</h4>
<p class="text-muted">欢迎您的登录!</p>
<a href="/page/siner/myprofile.jsp"
class="btn btn-rounded btn-danger btn-sm">个人信息</a>
</div>
</div>
</li>
<li role="separator" class="divider"></li>
<li><a href="/page/siner/myhome.jsp"><i class="ti-user"></i> 我的主页</a></li>
<li><a href="/page/siner/.myFavorite?classify=gallery&page=1&state=init"><i class="ti-wallet"></i> 我的收藏</a></li>
<li><a href=""><i class="ti-email"></i> 消息管理 </a></li>
<li role="separator" class="divider"></li>
<li><a href=""><i class="ti-settings"></i> 设置 </a></li>
<li role="separator" class="divider"></li>
<li><a href=".logoutServlet"><i class="fa fa-power-off"></i> 退出</a></li>
</ul>
</div>
</li>
</c:if>
三、这时用户关闭了浏览器,在打开浏览器访问网站时,浏览器会新建一个session,跟关闭客户端之前的session不一样,所以这里要用登录时保存在浏览器里的cookie来验证并自动登录。这里用Ajax指向一个VerifyCookieServlet。
Jsp页面javascript部分
<!-- 引入Ajax文件 -->
<script src="../../js/sin.js"></script>
<!-- 在页面定义全局变量,因为引入的JS文件获取不到sessionScope,但在这里定义一下,就可以取到 -->
<script type="text/javascript">
var nickname = '${sessionScope.nickname}';
var loginstate = '${sessionScope.loginstate}';
</script>
Ajax部分
$(document).ready(function() {
//获取当前访问页面地址
var pageurl = window.location.href;
//验证如果昵称和session自定义状态都为空时,调用Ajax
if(nickname == "" && loginstate == "") {
$.ajax({
//指向验证cookie的方法
url:".verifyCookieState",
success:function() {
//验证之后载入用户输入的访问页面
window.location.href = pageurl;
//载入登录显示区域,这里在URL后加入一个当前时间,因为ie对Ajax的调用模板的URL有一个缓存机制,如果URL不变会使用缓存的记录
var url = '/page/include/userlog.jsp?time=' + new Date().getTime();
$('.userlog').load(url);
}
});
} else {
//如果昵称不为空且state里存了“userhavedlogin”,代表用户已登录不需要验证cookie;或者昵称为空state里存了"visitnoneedlogin",代表用户为游客,不需要验证cookie
var url = '/page/include/userlog.jsp?time=' + new Date().getTime();
$('.userlog').load(url);
}
});
Servlet验证部分
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取session
HttpSession session = request.getSession();
//获取cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
//遍历从客户端获取的cookie
int lenght = cookies.length;
for (int i = 0; i < lenght; i++) {
Cookie c = cookies[i];
System.out.println("name:" + c.getName() + " value:" + c.getValue() + " age:" + c.getMaxAge());
//如果客户端的某个cookie中的name等于之前设置的"SINSESSION",说明该浏览器有本站设置的cookie
if ("SINSESSION".contentEquals(c.getName())) {
//通过cookie之前存储进去的用户ID,走DAO层,取出用户信息
user = userdao.getUserById(c.getValue());
// 把用户信息存储到当前会话的session中
session.setAttribute("userName", user.getUserName());
session.setAttribute("id", user.getId());
session.setAttribute("email", user.getEmail());
session.setAttribute("state", user.getState());
session.setAttribute("headimageurl", user.getHeadimageurl());
session.setAttribute("nickname", user.getNickname());
session.setAttribute("systemtime", user.getSystemtime());
//给session设置一个自定义变量,代表该用户已经登录了
session.setAttribute("loginstate", "userhavedlogin");
System.out.println("老用户回访: " + session.getAttribute("nickname"));
break;
} else if (i == lenght - 1 && !"SINSESSION".contentEquals(c.getName())) {
//如果一直遍历到最后一个cookie且仍不是本站设置的cookiename,就给登录状态设置为游客暂且不需要登录
session.setAttribute("loginstate", "visitnoneedlogin");
}
}
}
}
四、注销部分
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取当前会话的session
HttpSession session = request.getSession();
//取得登录的用户名
String userName = (String) session.getAttribute("userName");
System.out.println(userName+" is out");
//销毁session
session.invalidate();
//给名为SINSESSION的cookie复写,将cookie的生命周期设置为0,相当于从客户端销毁了cookie
Cookie cookie = new Cookie("SINSESSION","");
cookie.setPath("/");
cookie.setMaxAge(0);
//把复写的cookie返回给客户端
response.addCookie(cookie);
response.sendRedirect("/");
}
五、这样完成了验证登录的整体结构。注意的几个点:
1. Ajax调用模板的URL在IE下会有缓存影响,要在每次调用时改变URL,在地址结尾加随机参数。
2. action层处理完cookie验证后,一定不要忘了在返回Ajax成功的方法里,再次载入访问页面的地址,因为如果访问的页面是非用户页面,看不出问题,如果是用户有关的页面,比如用户收藏页面,会发现页面无用户数据内容,因为如果访问地址的数据请求和Ajax的验证同步请求,session中的用户ID肯定是空的,取不到用户数据,所以需要弄个拦截器先把访问地址的请求拦截下来,待cookie验证完以后,带着登录后的session再次载入访问地址。
3. 将Ajax的脚本放入js文件中,就可以方便每个页面引用,不用挨个粘贴一大段,但是引入的js文件无法获取sessionScope,所以要在所有页面,先定义好要所需内容的全局变量。