回顾:

响应: HttpServletResponse

行: 协议/版本 状态码(说明)

	200

	302(location)

	304

	404

	500

	setStatus();

	sendError();

头:  key/values

	setHeader("头名称","值");

		重定向:

			设置状态码 302

			location

		sendRedirect("重定向的路径");

		refresh

		content-type

		content-disposition

			设置两个头,一个流

体: 需要浏览器解析的内容

	getWriter(); 

	getOutputStream();

会话技术

会话概述:

会话: 一次通话.(不标准)

作用: 用来保存浏览器在访问服务器的过程中 产生的数据

Cookie:

概述:

英文直译:饼干; 小甜点

浏览器端的会话技术

作用:

将会话中产生的数据存放在浏览器端

==小结:==	

cookie存在浏览器上

cookie由服务器创建

cookie中存放的数据不安全

cookie中存到的数据量不超过4kb

cookie中存放的是文本信息(String)

工作流程

浏览器访问服务器时,服务器生成cookie(键值对形式),通过响应(响应头 set-cookie)返回给浏览器,cookie保存在浏览器上.

下次访问服务器的时候,根据一定的规则携带不同的cookie

将cookie装在请求头中带到服务器上   cookie头

==有关Cookie的API==

创建cookie

new Cookie(String name,String value);

返回给浏览器

response.addCookie(Cookie c);

意思为:给set-Cookie设置值

设置Cookie在浏览器的存活时间

注意:  cookie的默认存活时间为浏览器会话结束时(浏览器关闭)

setMaxAge(int 秒数);

如果秒数=0:删除该cookie(前提:路径必须相同)

设置路径

setPath(String cookie的路径);

默认路径:

	/day05/hello_cookie

	/day05

注意: 一旦给cookie设置了绑定路径,那么默认的绑定路径就会被覆盖.

测试cookie的默认绑定路径:
访问路径:  /day05/createCookie
名称		值		绑定路径
akey	 47			/day05
bkey	 bvalue		/day05
访问路径:  /day05/setMaxAge
ckey	 cvalue		/day05
访问路径:  /day05/aa/defaultPath
aakey	 aavalue	/day05/aa/
bbkey	 bbvalue	/day05/aa
结论: cookie的默认绑定路径为访问路径的上一层

获取请求中的所有cookie

request.getCookies();  数组接收 cookie[]

==// 浏览器携带cookie的规则==

 访问路径字符串包含原则

//访问路径 /day05/createCookie      (/day05   /day05/createCookie)
//	名称			值			绑定路径	
	akey	 	47				/day05
	bkey	 	bvalue			/day05
	ckey	 	cvalue			/day05
//访问路径 /day05/setMaxAge			(/day05   /day05/setMaxAge)
	akey	 	47				/day05
	bkey	 	bvalue			/day05
	ckey	 	cvalue			/day05
//访问路径 /day05/aa/defaultPath	(/day05   /day05/aa   /day05/aa/defaultPath)
	akey	 	47				/day05
	bkey	 	bvalue			/day05
	ckey	 	cvalue			/day05
	aakey	 	aavalue			/day05/aa
	bbkey	 	bbvalue			/day05/aa
	cbkey	 	ccvalue			/day05/aa

获取Cookie的名称

getName();

获取Cookie的值

getValue();

注意事项

cookie不能跨浏览器

cookie中存放的内容不能超过 4 kb

cookie中存放的是文本信息

通过服务器删除指定cookie对象:

将cookie的存活时间设置为 0 秒

创建相同名称 和 相同路径的cookie,将其覆盖

Session:

概述:

英文直译:开会,会议

服务器端的会话技术

作用:

在服务器上存放一次会话中的数据

==小结:==	

session存在服务器上

session由服务器创建

session中存放的数据相对安全

session中存放的数据量不受限制

session中可以存放一切数据(object)

工作流程

浏览器访问服务器时,服务器会获取浏览器的数据,判断浏览器是否携带了sessionID

如果没带:

	如果没带,且想使用session,需要先创建session(服务器端的内存空间,由服务器创建),这样以来就可以使用这个session了,使用完毕后将sessionID返回给浏览器,由浏览器保存sessionID(依赖Cookie)

如果带了:

	如果带了,服务器要先获取sessionID,根据sessionID找到这个session

	没找到:

		想使用session,需要先创建session(服务器端的内存空间,由服务器创建),这样以来就可以使用这个session了,使用完毕后将sessionID返回给浏览器,由浏览器保存sessionID(依赖Cookie)

	找到直接操作session

关于Session的API

获取一个session:

在java中我们认为第一次调用request.getSession()就是创建session空间

HttpSession session = request.getSession();

	创建session空间

	自动根据jsessionid找到session空间

Session的属性操作

setAttrbute(String name,object obj);

getAttrbute(name);

removeAttribute(String name);  

Session生命周期

创建:

java代码中第一次调用request.getSession()

不携带jsessionid也会创建

携带jsessionid但找不到对应的session也会创建

销毁:

服务器非正常关闭

session超时:tomcat默认超时时间为30分种

手动销毁:调用session.invalidate()方法

域对象(Servlet中的三大域对象)

ServletContext: 上下文对象

生命周期

	创建:服务器启动的时候,会为每一个项目创建一个servletContext对象

	销毁:服务器关闭的时候 或 项目从服务器上移出

	作用范围:整个项目

	作用:

		获取文件mime类型

		获取资源在服务器上的完整路径

		存放共享的数据

HttpSession: 会话

生命周期

	创建:调用request.getSession()时

	销毁:

		服务器非正常关闭

		Session超时

		手动销毁

			调用invalidate方法

	作用范围:一次会话

	作用:存放私有的数据

Request:请求

生命周期

	创建:请求来的时候

	销毁:响应生成的时候

作用范围:一次请求链中

作用:存放一次请求串中的数据

案例:

案例1-记录上次访问时间

需求分析:
	访问servlet记录访问时间
	如果用户是第一次访问该servlet,那么返回: "您是第一次访问,欢迎再来玩儿呀..."
    如果用户不是第一次访问则返回上一次访问的时间"...."
技术分析:
	cookie
步骤分析:
	

有一个数组 str = ["小张","小李","小王吧"....] 从该数组中查找是否有"小王吧".
    for(String value:str){
        if("小王吧".equals(value)){
            // 输出结果
            // 经理让这么写的,目的是让用户二次付费进行优化
            //break;
        }
    }

案例2-用户登录(验证码)

需求分析:
	带有验证码的用户登录.
技术分析:
	验证码:
		访问登录页面时需要生成验证码图片,并将生成的验证码保存到session中
	登录:
		用户名 密码 验证码
		// 首先校验验证码
		//1.获取session中生成的验证码
		//2.获取用户输入的验证码
		//3.校验....
		// 如果校验不通过,return
		// 通过后,执行登录

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<body>
    我是首页
    <form action="login" method="post">
        用户名: <input type="text" name="username"> <br>
        密码: <input type="password" name="password"> <br>
        验证码: <input type="text" name="ucode"> <img src="code" alt=""> <br>
        <input type="submit" value="登录">
    </form>

</body>
</html>

domain

package com.itheima.domain;

public class User {
    private int id;
    private String username;
    private String password;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }
}

dao

package com.itheima.dao;

import com.itheima.domain.User;
import com.itheima.utils.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

public class UserDao {
    // 登录
    public User login(User user) {
        try {
            JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
            String sql = "select * from user where username = ? and password = ? ";
            return template.queryForObject(sql,new BeanPropertyRowMapper<User>(User.class),
                    user.getUsername(),user.getPassword());
        } catch (DataAccessException e) {
            return null;
        }
    }
}

service

package com.itheima.service;

import com.itheima.dao.UserDao;
import com.itheima.domain.User;

public class UserService {

    public User login(User user) {
        UserDao dao = new UserDao();
        return dao.login(user);
    }
}

utils

package com.itheima.utils;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

@WebServlet(name = "CodeServlet",urlPatterns = "/code")
public class CodeServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		// 使用java图形界面技术绘制一张图片

		int charNum = 4; // 生成4位的验证码
		int width = 20 * 4; // 图片宽
		int height = 28; // 图片高

		// 1. 创建一张内存图片
		BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		// 2.获得绘图对象
		Graphics graphics = bufferedImage.getGraphics();

		// 3、绘制背景颜色
		graphics.setColor(Color.YELLOW);
		graphics.fillRect(0, 0, width, height);

		// 4、绘制图片边框
		graphics.setColor(Color.GRAY);
		graphics.drawRect(0, 0, width - 1, height - 1);

		// 5、输出验证码内容
		graphics.setColor(Color.RED);
		graphics.setFont(new Font("宋体", Font.BOLD, 22));
		
		// 随机输出4个字符
		String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789";
		Random random = new Random();
		
		// session中要用到
		String msg = "";
		
		int x = 5;
		for (int i = 0; i < charNum; i++) {
			int index = random.nextInt(32);
			String content = String.valueOf(s.charAt(index));
			
			msg += content;
			graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
			graphics.drawString(content, x, 22);
			x += 20;
		}
		// 保存到session中
        request.getSession().setAttribute("scode",msg);

		// 6、绘制干扰线
		graphics.setColor(Color.GRAY);
		for (int i = 0; i < 5; i++) {
			int x1 = random.nextInt(width);
			int x2 = random.nextInt(width);

			int y1 = random.nextInt(height);
			int y2 = random.nextInt(height);
			graphics.drawLine(x1, y1, x2, y2);
		}

		// 释放资源
		graphics.dispose();

		// 图片输出 ImageIO
		ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request,response);
	}

}

web

package com.itheima.web;

import com.itheima.domain.User;
import com.itheima.service.UserService;
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        try {
            //------------------------ 校验验证码
            //a.获取session中的验证码
            HttpSession session = request.getSession();
            String scode = (String) session.getAttribute("scode");
            // 删除session中的验证码
            session.removeAttribute("scode");
            //b.获取用户输入的验证码
            String ucode = request.getParameter("ucode");
            System.out.println(scode+" : "+ucode);
            //c.校验
            if(ucode==null || ucode.equals("")){
                response.getWriter().print("验证码不可为空..");
                return;
            }

            if(!ucode.equalsIgnoreCase(scode)){
                response.getWriter().print("验证码输入错误..");
                return;
            }



            //-------------------------
            //1.编写loginServlet
            //2.在servlet中获取用户名和密码
            Map<String, String[]> map = request.getParameterMap();
            User user = new User();
            //user.setUsername(map.get("username")[0]);
            //user.setPassword(map.get("password")[0]);
            //3.调用service处理业务逻辑
            BeanUtils.populate(user,map);
            UserService service = new UserService();
            User u = service.login(user);
            //4.判断执行结果,生成响应信息
            if(u!=null){
                response.getWriter().print("登录成功");
            }else {
                response.getWriter().print("登录失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().print("当前功能正在维护...");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

总结:

1. 能够说出会话的概念
	保存浏览器和服务器交互时产生的数据信息
2. 能够说出cookie的概念
	浏览器
3. 能够创建、发送、接收、删除cookie
4. 能够说出cookie执行原理
5. 能够说出session的概念
6. 能够获取session对象、添加、删除、获取session中的数据
7. 能够完成登录验证码案例