1、session的作用

  用户用浏览器访问web服务器时,会为每个用户创建一个session(会话),session在用户关闭浏览器之前都是有效的,所以我们可以在session中保存用户的一些信息,以供使用。这里我们用session保存用户的账号名称,以表示用户已经登录,可以直接访问后台页面。

2、cookie的作用

  cookie是客户端保存的一些少量数据,每次用户通过浏览器访问web服务器时,cookie可以通过request一起传送至服务器端,这里我们使用cookie保存用户的账号密码,以便实现自动登录功能。

说明:实现过程分为两个页面

  1. login.jsp 是前台登录界面分别有账号、密码输入区,以及一个是否自动登录的复选框,一个选择保存时长的下拉列表框,如下图所示:

在这里插入图片描述

  1. mypage.jsp是登录后的显示界面,有一个注销按钮,以便用户登出。

在这里插入图片描述

3、流程

  • 用户访问login.jsp进行第一次登录,对应的servlet将提交的用户名与密码和数据库中的记录进行匹配,如果:
    • 匹配失败(要考虑用户名和密码为空的情况),则返回login.jsp进行再次登录,并且报告错误信息(记住提交URL参数中的中文需要用URLEncoder进行编码,不然会乱码)
    • 匹配成功 (cookie是保存在客户端的,程序中进行配置之后一定需要用response.addCookies将cookie添加至response从而发回客户端浏览器)
      • 如果选择了未自动登录,此时从request中取出原来的cookies,将有效时间设为0,表示不再进行自动登录。
      • 如果选择了自动登录,那么就要创建两个新的cookie,一个保存username,一个保存passwd(安全的做法是用MD5等加密算法加密后保存),并根据选择的有效时间设置cookie的有效时间
      • 之后用reque.getsession.setAttribute()设置username属性表示用户已经登录,最后将页面重定向至mypage.jsp

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub


String command= request.getParameter("command");
//这里是用户登录的界面,需要处理逻辑关系,考虑
if(command.equals("login"))
{
//1、没有输入用户名 2、用户名错误 3、密码错误
String username = request.getParameter("username");
String passwd = request.getParameter("passwd");
//如果未输入用户名
if(username.equals("")||passwd.equals(""))
{
System.out.println("未输入用户名");
String error_msg = "请输入用户名和密码";
String error =URLEncoder.encode(error_msg, "utf-8");
response.setCharacterEncoding("utf-8");
response.sendRedirect("/MyDBtest/login.jsp?error="+error);
}
//对用户名进行查询
else
{
String real_passwd = loginChecker.getPasswd(username);
//没有此用户
if(real_passwd.equals(""))
{
System.out.println("没有此用户");
String error_msg = "没有此用户,请重新输入用户名";
String error =URLEncoder.encode(error_msg, "utf-8");
response.setCharacterEncoding("utf-8");
response.sendRedirect("/MyDBtest/login.jsp?error="+error);
}

//查询成功 检查用户是否设置自动登录,如果是则发送cookies
else if(real_passwd.equals(passwd))
{
//设置session username属性表示用户已经登录
request.getSession().setAttribute("username", username);

//检查用户是否选择自动登录
//如果选择了自动登录,则需要保存cookies

if("on".equals(request.getParameter("autologin")))
{
int saveTime = Integer.parseInt(request.getParameter("maxage"));
saveTime =24*60*60*saveTime;
Cookie user_cookie = new Cookie("username", username);
Cookie passwd_cookie = new Cookie("passwd", passwd);
user_cookie.setMaxAge(saveTime);
passwd_cookie.setMaxAge(saveTime);
response.addCookie(user_cookie);
response.addCookie(passwd_cookie);

}
//如果没有选择自动登录
else
{
Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies)
{
System.out.println("删除 cookie");
if(cookie.getName().equals("username"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //添加生成的新的cookie
}
else if(cookie.getName().equals("passwd"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //添加生成的新的cookie
}
}

}
//重定向到后台界面
response.sendRedirect("/MyDBtest/mypage.jsp");
}
//密码错误
else {
System.out.println("密码错误");
String error_msg = "密码错误,请重新输入密码";
String error =URLEncoder.encode(error_msg, "utf-8");
response.setCharacterEncoding("utf-8");
response.sendRedirect("/MyDBtest/login.jsp?error="+error);
}
}
}
else if(command.equals("deleteCookies"))
{
//用户主动注销,那么不用再保存Cookies
Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies)
{
if(cookie.getName().equals("username"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //设置失效
}
else if(cookie.getName().equals("passwd"))
{
cookie.setMaxAge(0);
response.addCookie(cookie); //设置失效
}
}

//重定向到登录界面
request.getSession().removeAttribute("username");
response.sendRedirect("/MyDBtest/login.jsp");
}
}

}

  • 对于访问mypage.jsp,步骤如下:
    • 首先检查session是否有username属性,如果存在那么可以直接访问mypage.jsp,若不存在则进行下一步判断
    • 取出request中的cookie(考虑为空的情况),取出用户名和密码,与数据库中记录进行匹配,若匹配成功,则设置session的username属性,表示已经登录成功,然后跳转至mypage.jsp
    • 若与数据库匹配失败或者cookie为空,那么可将页面重定向至错误页面,提示用户进行登录后才能访问。

不难想到,应该为 mypage.jsp设置一个过滤器,每次访问该页面,先由过滤器完成上述流程,过滤器配置如下:

1
2
3
4
5
6
7
8
9
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>Filter.LoginFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/mypage.jsp</url-pattern>
</filter-mapping>

过滤器代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here

//访问 mypage 页面前需要经过此过滤器
//System.out.println("进入到后台登录过滤器");
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;



//这里说明用户未登录,那么获取cookies并验证是否能登录
if(req.getSession().getAttribute("username")==null )
{

System.out.println("进入到后台登录过滤器");
Cookie[] cookies = req.getCookies();
String username=null;
String passwd=null;
if(cookies!=null)
{
for(Cookie cookie:cookies)
{
if(cookie.getName().equals("username"))
{
username = cookie.getValue();
}
else if(cookie.getName().equals("passwd"))
{
passwd =cookie.getValue();
}
}
}
if(username!=null&&passwd!=null)
{
//匹配数据中的用户名以及密码
//匹配成功则设置登录,否则退出登录
if(loginChecker.getPasswd(username).equals(passwd))
req.getSession().setAttribute("username", username);
}

}



// pass the request along the filter chain
chain.doFilter(req, res);
}

mypage.jsp页面还有一个注销按钮,用户注销后,servlet应该主动删除用户的cookie信息。