Cookie&Session

Cookie&Session

1. 什么是会话?

会话简单理解为:用户打开一个浏览器,点击多个超链接访问服务器的web资源,然后关闭浏览器,整个过程称为是一次会话。

2. 会话技术分类

2.1 Cookie技术

Cookie是客户端技术,程序把每个用户的数据以cookie的形式保存到各自浏览器中。当用户使用浏览器再次访问服务器中的web资源的时候,就会带着各自的数据过去。这样,web资源处理的就是用户各自的数据了。

2.2 Session技术

Session是服务器端技术,利用这个技术,服务器在运行时为每一个用户的浏览器创建一个独享的session对象。由于session为用户浏览器独享,所有用户在访问服务器的时候,可以把各自的数据放在各自的session中,当用户再次访问服务器中的web资源的时候,其他web资源再从用户各自的session中取出数据为用户服务。

3. 会话技术的实现原理

3.1 Cookie的实现原理

img

3.2 Session的实现原理

img

  • 获得从浏览器带过来的Cookie:

    img

  • 向浏览器回写Cookie:

    img

  • Cookie的构造

    img

4.2 Cookie的API的概述

  • ​ 获得Cookie的名称的方法

    img

  • 获得Cookie的值的方法

    img

  • 设置Cookie的有效域名

    img

  • 设置Cookie的有效路径

    img

  • 设置Cookie的有效时长

    img

5. Session

5.1 Session的API的使用

  • 向session中存入数据

    img

  • 从session域中获取数据

    img

  • 从session域中移除数据

    img

5.2 为什么有Cookie还要有Session

  • Cookie局限性:
    Cookie保存的数据是有个数和大小的限制的。
      数据是保存客户端浏览器上(相对不是很安全)。
  • Session
    Session没有个数和大小限制。
    数据是保存在服务器上(相对比较安全)。

6. Servlet的数据访问范围的总结

6.1 请求范围(ServletRequest)

  • 何时创建和销毁的

    创建:当用户向服务器发送一次请求,服务器创建一个request对象。
      销毁:当服务器对这次请求作出了响应,服务器就会销毁这个request对象。
  • 如何存取数据
    存数据:

    ​ void setAttribute(String name,Object value);

    取数据

    Object getAttribute(String name);

    作用范围

    作用范围:一次请求。(转发就是一次请求)。

6.2 会话范围(HttpSession)

  • 何时创建和销毁的
    创建:服务器端第一次调用getSession()方法的时候。
      销毁:三种情况。
              Session过期,默认的过期时间30分钟(web.xml中配置)。
              非正常关闭服务器。(正常关闭服务器—session会被序列化)。
              手动调用session.invalidate();
  • 如何存取数据
    存数据:
             void setAttribute(String name,Object value);
     取数据
             Object getAttribute(String name);
     作用范围
             作用范围:一次会话(多次请求)

6.3 应用范围(ServletContext)

  • 何时创建和销毁的
    创建:服务器启动的时候创建,为每个web项目创建一个单独ServletContext对象。 
      销毁:服务器关闭的时候,或者项目从服务器中移除的时候。
  • 如何存取数据
    存数据:
              void setAttribute(String name,Object value);
      取数据
              Object getAttribute(String name);
      作用范围
              作用范围:整个应用

7.用户登录代码

7.1 Controller

loginServlet

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
import java.io.IOException;
import java.net.HttpCookie;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import model.loginModel;
import domain.User;

/**
* loginServlet
*/
public class loginController extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
try {
// 获取数据
// 解决获取请求数据中文乱码
// 校验验证码
String checkcode1 = request.getParameter("checkcode");
String checkcode2 = (String) request.getSession().getAttribute(
"checkcode");

if (!checkcode1.equalsIgnoreCase(checkcode2)) {
request.setAttribute("msg", "验证码错误");
request.getRequestDispatcher("/login.jsp").forward(request,
response);
return;
}

request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");

// 封装数据
User user = new User();
user.setUsername(username);
user.setPassword(password);
// 处理数据
loginModel loginModel = new loginModel();
User existuser = loginModel.login(user);
// 根据处理结果跳转页面
if (existuser == null) {
// 登陆失败
request.setAttribute("msg", "用户名或密码错误!");
request.getRequestDispatcher("/login.jsp").forward(request,
response);
} else {
// 登陆成功
// 判斷是否记住用户名
String remember = request.getParameter("remember");
if (remember != null) {
if (remember.equals("true")) {
Cookie cookie = new Cookie("username",
existuser.getUsername());
// 设置路径
cookie.setPath("/web03_login");
// 设置时间
cookie.setMaxAge(60 * 60 * 24);
// 写回浏览器
response.addCookie(cookie);
}
}

HttpSession session = request.getSession();
session.setAttribute("user", existuser);
response.sendRedirect("/web03_login/success.jsp");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

CheckImgServlet

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* 生成验证码图片
*
*
*/
public class CheckImgServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 禁止缓存
// response.setHeader("Cache-Control", "no-cache");
// response.setHeader("Pragma", "no-cache");
// response.setDateHeader("Expires", -1);

int width = 120;
int height = 30;

// 步骤一 绘制一张内存中图片
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);

// 步骤二 图片绘制背景颜色 ---通过绘图对象
Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔
// 绘制任何图形之前 都必须指定一个颜色
graphics.setColor(getRandColor(200, 250));
graphics.fillRect(0, 0, width, height);

// 步骤三 绘制边框
graphics.setColor(Color.WHITE);
graphics.drawRect(0, 0, width - 1, height - 1);

// 步骤四 四个随机数字
Graphics2D graphics2d = (Graphics2D) graphics;
// 设置输出字体
graphics2d.setFont(new Font("宋体", Font.BOLD, 18));

String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
Random random = new Random();// 生成随机数

// 定义x坐标
int x = 10;
// 创建StringBuffer对象
StringBuffer b = new StringBuffer();
for (int i = 0; i < 4; i++) {
// 随机颜色
graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random
.nextInt(110), 20 + random.nextInt(110)));
// 旋转 -30 --- 30度
int jiaodu = random.nextInt(60) - 30;
// 换算弧度
double theta = jiaodu * Math.PI / 180;

// 生成一个随机数字
int index = random.nextInt(words.length()); // 生成随机数 0 到 length - 1
// 获得字母数字
char c = words.charAt(index);
// 拼接字符
b.append(c);
// 将c 输出到图片
graphics2d.rotate(theta, x, 20);
graphics2d.drawString(String.valueOf(c), x, 20);
graphics2d.rotate(-theta, x, 20);
x += 30;
}
// 将拼接的StringBuffer转换成字符串
String checkcode = b.toString();
// 将字符串存入session中
request.getSession().setAttribute("checkcode", checkcode);

// 步骤五 绘制干扰线
graphics.setColor(getRandColor(160, 200));
int x1;
int x2;
int y1;
int y2;
for (int i = 0; i < 30; i++) {
x1 = random.nextInt(width);
x2 = random.nextInt(12);
y1 = random.nextInt(height);
y2 = random.nextInt(12);
graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
}

// 将上面图片输出到浏览器 ImageIO
graphics.dispose();// 释放资源
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* 取其某一范围的color
*
* @param fc
* int 范围参数1
* @param bc
* int 范围参数2
* @return Color
*/
private Color getRandColor(int fc, int bc) {
// 取其随机颜色
Random random = new Random();
if (fc > 255) {
fc = 255;
}
if (bc > 255) {
bc = 255;
}
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
}

logOutServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class logoutServlet
*/
public class logoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 清除session
request.getSession().invalidate();
// 跳转
response.sendRedirect("/web03_login/success.jsp");
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

7.2 Model

loginModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.sql.SQLException;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import utils.JDBCUtils;
import domain.User;

public class loginModel {
public User login(User user) throws SQLException {
QueryRunner q = new QueryRunner(JDBCUtils.getDataSource());
User existuser = q.query(
"select * from user where username = ? and password = ?",
new BeanHandler<User>(User.class), user.getUsername(),
user.getPassword());
return existuser;
}
}

7.3 Domain

User

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
public class User {
private int uid;
private String username;
private String password;
private String nickname;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}

7.4 Utils

JDBCUtils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.sql.Connection;
import java.sql.SQLException;

import org.apache.tomcat.jdbc.pool.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class JDBCUtils {
private static final ComboPooledDataSource d = new ComboPooledDataSource();

public static Connection getConnection() throws SQLException {
return d.getConnection();
}

public static ComboPooledDataSource getDataSource() {
return d;
}
}

7.5 配置文件

c3p0-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///web02</property>
<property name="user">root</property>
<property name="password">abc</property>

<property name="initialPoolSize">5</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>

</c3p0-config>

7.6 JSP页面

login.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
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登陆</title>
<script type="text/javascript">
function changeIMG() {
document.getElementById("i1").src = "/web03_login/CheckImgServlet?time="
+ new Date().getTime();
}
</script>
</head>
<body>
<%
String msg = "";
if (request.getAttribute("msg") != null) {
msg = (String) request.getAttribute("msg");
}
%>
<h1>登陆页面</h1>
<h3>
<font color="red"> <%=msg%></font>
</h3>
<form action="/web03_login/loginController" method="post">
<table border="2" width="400">
<tr>
<td>用户名:</td>
<td><input type="text" name="username"
value="${cookie.username.value }"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>验证码:</td>
<td><input type="text" name="checkcode" size="6"> <img
id="i1" src="/web03_login/CheckImgServlet"><a href="#"
onclick="changeIMG()">看不清,换一张</a></td>
</tr>
<tr>
<td><input type="checkbox" name="remember" value="true"></td>
<td>记住用户名</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登陆"></td>
</tr>
</table>
</from>
</body>
</html>

success.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
<%@page import="domain.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
if (request.getSession().getAttribute("user") == null) {
%>
<h1>
你还没有登陆!请去<a href="/web03_login/login.jsp">登陆</a>
</h1>
<%
} else {
User user = (User) request.getSession().getAttribute("user");
%>
<h1>登陆成功!</h1>
<h3>
你好!<%=user.getNickname()%></h3>
<a href="/web03_login/logoutServlet">退出</a>

<%
}
%>
</body>
</html>