第一章 会话技术
1、会话技术概述
目标: 解释说明会话技术的概念
步骤:
1、概念:为完成一个网络上的活动,用户打开浏览器多次请求服务器的资源,然后关闭浏览器。整个过程称之为一个会话;
2、生活中的网购场景演示:
小结:
1、会话概念:为完成一次网络上的活动,用户打开浏览器多次请求服务器,服务器给出多次响应。然后关闭服务器,这个过程称之为一次会话。
简而言之:会话就是由多次请求和响应组成的一次网络上的活动;
2、会话过程中要解决的问题
目标: 解释说明会话过程中要解决的问题
步骤:
1、多次请求和响应之间需要存储数据;
2、分析数据为什么不能存储在数据库中;
3、只能存在与BS交互双方中的任意一方;
实现:
1、多次请求和响应之间需要存储数据;
未登录情况下,往购物车中添加商品,关闭服务器后商品任然存在,说明数据被存储起来了。
2、数据为什么不能存储在数据库中;
1、用户未登录,无法标识购物车中商品所属用户,存储在数据库中不便于查询;
2、对数据库造成查询压力;
3、将数据存储在BS双方,且在多次请求和响应之间共享数据使用的技术:
Cookie技术:将数据存储在浏览器端;
Session技术:将数据存储在服务器端;
特点:能够在多次请求和响应之间共享。
小结:
1、会话期间需要解决的问题:数据存储
2、会话期间存储数据的技术:会话技术
Cookie:将数据存储在浏览器端
Session:将数据存储在服务器端
3、会话技术存储数据的特点:在多次请求和响应之间共享
第二章 Cookie技术
1、Cookie概述
目标:解释说明Cookie概念
步骤:
1、概念:Cookie指的是少量信息;
2、Cookie的产生:Cookie通常是由web服务器创建,发送给客户端(浏览器),并保存在客户端;
3、查看浏览器中的Cookie:打开Chrome浏览器,查看Cookie数据;
实现:
1、概念:Cookie指的是少量信息;
2、Cookie的产生:
1、创建:由web服务器创建,并发送给浏览器;
2、保存:保存在浏览器端(硬盘上);
3、查看浏览器中的Cookie:打开Chrome浏览器,查看Cookie数据;
谷歌浏览器将cookie保存到:C:\Users\用户名\AppData\Local\Google\Chrome\User Data\Default目录。
小结:
1、Cookie技术:在浏览器端保存小量信息的技术;
2、Cookie数据的产生:
创建:web服务器创建,发送给浏览器
保存:浏览器端存储(硬盘上)
2、Cookie的应用场景
Cookie通常是将通过浏览器访问服务器的用户的信息存储在浏览器中用以标识用户。常见的应用场景有:1、自动登录;2、记住登录用户名和密码信息;
3、Cookie基本API
目标: 掌握Cookie的基本API
步骤:
第一步:解释说明Cookie的基本API;
创建: Cookie cookie = new Cookie(name,value);
获取name值: String name = cookie.getName();
获取value值: Strign value = cookie.getValue();
发送cookie: response.addCookie(cookie);
设置cookie的值: cookie.setValue(value);
获取所有cookie: Cookie[] getCookies() = rquest.getCookies();
第二步:创建一个Servlet–CookieApiServlet演示以上方法;
第三步:观察浏览器中存储的Cookie信息和控制台中打印输出的Cookie信息。
实现:
第一步:创建一个Servlet–CookieApiServlet演示以上方法;
package com.heima.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author buguniao
* @version v1.0
* @date 2018/12/14 10:21
* @description TODO
**/
@WebServlet("/cookieApiServlet")
public class CookieApiServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Cookie基本API的使用
//1、创建Cookie
Cookie cookie = new Cookie("name","张三");
//2、发送Cookie
response.addCookie(cookie);
//3、获取Cookie的name值
String name = cookie.getName();
System.out.println(name);
//4、获取Cookie的value值
String value = cookie.getValue();
System.out.println(value);
//5、设置Cookie的value值4
cookie.setValue("李四");
//6、获取所有的Cookie
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
System.out.println("name="+c.getName()+";value="+c.getValue());
}
}
}
小结:
1、Cookie创建:
2、发送Cookie:
3、获取Cookie的name值和value值:
4、request中为什么会有Cookie:
5、获取Cookie的方法:
4、记住用户名和密码案例
目标: 使用Cookie技术记住用户名和密码案例
步骤:
1、前端:
【1】在登录页面上添加一个记住我复选框;
【2】填写登录信息,并提交表单数据到处理登录业务逻辑的Servlet;
2、后台:
【1】获取记住我 复选框的勾选状态,如果被勾选,则处理记住密码业务;
【2】记住密码业务处理:
第一步:用户登录成功之后,获取用户的用户名和密码;
第二步:创建Cookie对象,保存用户的用户名和密码信息;
第三步:将Cookie发送给浏览器保存;
3、前端:
【1】登录页面加载完成后,判断cookie中是否有用户名和密码信息,如果有,则将用户名和密码信息从浏览器中提出出来,动态更新到用户名和密码文本框中。
实现:
1、前端:
【1】在登录页面上添加一个记住我复选框;
【2】填写登录信息,并提交表单数据到处理登录业务逻辑的Servlet;
2、后台:
【1】获取记住我 复选框的勾选状态,如果被勾选,则处理记住密码业务;
【2】记住密码业务处理:
第一步:用户登录成功之后,获取用户的用户名和密码;
第二步:创建Cookie对象,保存用户的用户名和密码信息;
第三步:将Cookie发送给浏览器保存;
//3、响应数据
if (loginFlag) {
//如果记住我复选框被勾选
if ("remember-me".equals(rememberMe)) {
//处理记住密码业务逻辑
Cookie nameCookie = new Cookie("name", name);
Cookie pwdCookie = new Cookie("password", password);
//将Cookie发送给浏览器
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
}
//登录成功 重定向到成功页面
response.sendRedirect("/success.html");
}
3、前端:
【1】登录页面加载完成后,判断cookie中是否有用户名和密码信息,如果有,则将用户名和密码信息从浏览器中提出出来,动态更新到用户名和密码文本框中。
【commons.js】
上述js代码中:cookie.getCookie()方法被封装在common.js中,使用前,先导入common.js文件。
var cookie = {
getCookie: function (key) {
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}
};
4、观察案例的实现结果;
【1】访问:"/test/a";
【2】访问:"/test/a/b"
【3】访问:"/test"
小结:
xxxxxxxxxx 1、Cookie的有效路径:Cookie能够被访问到的路径;2、Cookie有效路径特点:能够在有效路径或其子路径下获取到Cookie;3、有效路径: 通常设置Cookie的有效路径为"/"或不设置;
5、Cookie的存活时间
目标: 解释说明Cookie的存活时间和存活时间的设置
步骤:
1、解释说明Cookie的分类:
会话级别的Cookie
持久型的Cookie
2、会话级别的Cookie:
概念:我们创建的Cookie对象默认是会话级别的Cookie,浏览器关闭后Cookie立即销毁;
演示:
3、持久型的Cookie:
持久型的Cookie:浏览器关闭后能够保存一段时间;
4、Cookie最大存活时间的设置:
void setMaxAge(int seconds);
实现:
1、会话级别Cookie的创建及销毁演示:
第一步:打开上面实现的记住账号和密码案例;
第二步:关闭浏览器发现Cookie消失;
2、持久型Cookie的设置:设置Cookie的最大存活时间:
//处理记住密码业务逻辑
Cookie nameCookie = new Cookie("name", name);
Cookie pwdCookie = new Cookie("password", password);
//设置Cookie的最大存活时间
nameCookie.setMaxAge(60*60);
pwdCookie.setMaxAge(60*60);
//将Cookie发送给浏览器
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
小结:
1、Cookie分类:会话级别,持久型;
2、Cookie创建后:默认是会话级别的;
3、设置Cookie的最大存活时间:cookie.setMaxAge(int second);
6、Cookie的有效路径
目标: Cookie有效路径的设置及应用场景
步骤:
1、概念:Cookie有效路径–cookie允许被访问的路径。
2、特点:Cookie在其设置的有效路径和其子路径下能够被访问到;
3、案例演示:
第一步:创建Servlet--CookiePathServlet,设置一个Cookie("name","Hello Cookie!")的有效路径为"/web/a";
第二步:分别创建测试Servlet:CookieDemo1Servlet("/test/a"),CookieDemo2Servlet("/test/a/b"),CookieDemo3Servlet("/test");
第三步:分别在测试Servlet中获取Cookie("name","Hello Cookie!");
4、观察案例的实现结果;
实现:
1、概念:Cookie有效路径–cookie允许被访问的路径。
2、特点:Cookie在其设置的有效路径和其子路径下能够被访问到;
3、案例演示:
第一步:创建Servlet--CookiePathServlet,设置一个Cookie("name","Hello Cookie!")的有效路径为"/test/a";
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建Cookie,并设置有效路径为"/web/a"
Cookie cookie = new Cookie("name", "HelloCookie!");
//设置有效路径
cookie.setPath("/test/a");
//发送cookie
response.addCookie(cookie);
}
第二步:分别创建测试Servlet:CookieDemo1Servlet("/test/a"),CookieDemo2Servlet("/test/a/b"),CookieDemo3Servlet("/test");
第三步:分别在测试Servlet中获取Cookie(“name”,“HelloCookie!”);
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
if ("name".equals(c.getName())) {
System.out.println("name="+c.getName()+";value="+c.getValue());
}
}
}
4、观察案例的实现结果;
【1】访问:"/test/a";
【2】访问:"/test/a/b"
【3】访问:"/test"
小结:
1、Cookie的有效路径:Cookie能够被访问到的路径;
2、Cookie有效路径特点:能够在有效路径或其子路径下获取到Cookie;
3、有效路径:
通常设置Cookie的有效路径为"/"或不设置;
7、Cookie删除
目标: 使用java代码删除Cookie
步骤:
实现:删除有效路径为"/test/a"的cookie;
第一步:创建一个Servlet–CookieDelServlet;
package com.heima.cookie;
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.io.IOException;
/**
* @author buguniao
* @version v1.0
* @date 2018/12/14 11:26
* @description TODO
**/
@WebServlet("/cookieDelServlet")
public class CookieDelServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
第二步:在CookieDelServlet中创建一个与要删除的cookie同名的cookie,将其值设置成"";
第三步:将这个cookie的最大存活时间设置成0;
第四步:设置这个cookie的有效路径(与原cookie的有效路径一致);
第五步:将这个新的cookie响应给浏览器,置换原来的cookie;
第五步:访问DelCookieServlet,观察浏览器中这个Cookie是否还存在:
小结:
8、Cookie小结
- Cookie:服务器在客户端(浏览器)存储数据的技术;
- Cookie分类:
- 会话级别:没有设置最大存活时间的cookie,浏览器关闭后消失;
- 持久级别:设置了最大存活时间,浏览器关闭后不会消失;
- Cookie基本API:
- 创建Cookie:Cookie c = new Cookie("name","zhangsan");
- 获取name值:c.getName();
- 获取value值:c.getValue();
- 将cookie响应给浏览器:response.add(c);
- 获取所有的cookie:Cookie[] cookies = request.getCookies();
- Cookie的有效时间:
- setMaxAge(int seconds):以秒为单位设置cookie的存活时间;
- Cookie的有效路径:
- setPath(String path):设置cookie的有效路径,在这个路径及其子路径下有效;
- Cookie删除:
- 客户端:
- 会话级别的cookie,关闭浏览器后cookie立即消失;
- 禁用cookie;
- 手动清除cookie;
- 服务端:
- 通过Servlet,将原来的cookie置换;
- Cookie的优势及弊端:
- 优势:
- 为服务端标识用户提供依据;
- 减轻了服务端数据存储的压力;
- 弊端:
- 数据存储在客户端不安全;
- 存储的数据大小受限,一个cookie存储的数据最大为4K;
第三章 Session技术
1、Session概述
目标: 解释说明Session的概念及作用
步骤:
1、概念:Session是服务器为每个访问这个服务器的客户端用户创建的一个容器。
2、作用:这个容器中存储的数据能够在多个request之间实现共享。
3、特点:服务器为每个访问这个服务器的客户端用户创建的一个容器。
实现:
画图描述一下概念:
1、概念:Session是服务器为每个访问这个服务器的客户端用户创建的一个容器。
2、作用:这个容器中存储的数据能够在多个request之间实现共享。
3、特点:服务器为每个访问这个服务器的客户端用户创建的一个容器。
2、Session的应用场景
凡是需要为每个用户在服务器端保存数据的,我们都可以使用Session来实现。Session最常见的应用场景:1、登录成功之后,将用户数据保存在session中;2、验证码校验过程中,将服务器端生成的验证码保存在session中;
目标:理解Session应用场景----登录成功之后,将用户数据保存在session中
步骤:
1、描述日常生活中的网购场景:添加购物车需要用户信息,下订单需要用户信息;
2、服务器获取用户信息的途径:用户登录;
3、需要处理的问题:登录成功之后,创建session对象,保存用户数据,在服务器内部共享;
小结:
1、描述日常生活中的网购场景:添加购物车需要用户信息,下订单需要用户信息;
2、服务器获取用户信息的途径:用户登录;
3、需要处理的问题:登录成功之后,创建session对象,保存用户数据,在服务器内部共享;
3、Session常用API(重要)
Session常用API包括:创建session,往session容器中存储数据,删除数据,获取数据
方法 使用示例 说明
request.getSession(); request.getSession(); 获取当前session
void setAttribute(String name,Object value) session.setAttribute(“loginUser”,user) 将一个对象与一个名称关联
之后存储到session中
Object getAttribute( String name) session.getAttribute(“loginUser”) 通过名称获取session
中的数据
void removeAttribute(String name) session.removeAttribute(“loginUser”) 根据指定名称删除
session中的数据
String sessionId = session.getId(); session.getId() 获取session的id
invalidate() ression.invalidate() 使当前session失效
目标:演示Session常用API
步骤:
1、创建Servlet–SessionAPIServlet,分别演示获取session,session存值,取值,移除值,获取id,销毁session方法;
2、Debug观察运行结果;
实现:
1、创建Servlet–SessionAPIServlet,分别演示获取session,session存值,取值,移除值,获取id,销毁session方法;
2、Debug观察运行结果;
package com.heima.session;
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;
/**
* @author buguniao
* @version v1.0
* @date 2018/12/14 12:54
* @description TODO
**/
@WebServlet("/sessionAPIServlet")
public class SessionAPIServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Session基本API演示
//1、创建Session
HttpSession session = request.getSession();
//2、存值
session.setAttribute("name", "张三");
//3、取值
String name = (String) session.getAttribute("name");
System.out.println(name);
//4、移除值
session.removeAttribute("name");
//5、获取session的id
String sessionId = session.getId();
System.out.println(sessionId);
//6、销毁session
session.invalidate();
}
}
小结:
Session基本API:
4、Session标识用户的原理
目标:解释说明Session标识用户的原理
步骤:
小结:
1、Session标识用户的本质:Session通过服务器标识浏览器;
2、Session标识用户的实现:基于Cookie;
3、Session标识用户的流程:
第一步:第一次创建session对象时,服务器把sessionid以Cookie的形式发送给浏览器;
第二步:浏览器第二次访问服务器的时候,会携带这个Cookie;
第三步:服务器根据浏览器上次存储在Cookie中的sessionId,查找到上次的Session;
5、Session的生命周期(了解即可)
5.1 Session创建
创建时机:第一次调用reqeust.getSession(); tomcat创建
使用session:域对象
作用:存储数据 API: setAttribute(name,value) getAttribute(name)
特点:在服务器端共享数据(多次请求和响应之间)
销毁:
1、session手动销毁:session.invilidate();
2、过期销毁:session默认存活时间--30min
3、非正常关闭tomcat;
当客户端浏览器第一次访问服务器时,服务器为每个浏览器创建不同的HttpSession对象。在服务器端使用request.getSession()方法来获得HttpSession对象
当第一次执行 request.getSession()是session对象就被创建了。后续的request.getSession()只能获取已创建的session。
5.2 Session使用
对下载案例进行修改,要求用户登录以后才能下载,没有登录,点击下载标签,让用户去登录页面进行登录
login.html
Title
LoginServlet.java
package cn.itheima.login;
import cn.itheima.domain.User;
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.io.IOException;
/**
* Created by IntelliJ IDEA
*
* @author: admin
* Date: 2018/8/23
* Time: 11:56
*/
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = new User();
user.setName(username);
user.setPassword(password);
//获取session 将用户信息保存在session中
request.getSession().setAttribute("user",user);
//去下载页面进行下载
response.sendRedirect("download.html");
}
}
对下载代码进行修改
DownloadServlet.java
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取session中user对象
User user = (User) request.getSession().getAttribute("user");
if (null == user){
response.sendRedirect("login.html");
}else {
//获取文件名
String filename = request.getParameter("filename");
//获取文件路径
String path = request.getServletContext().getRealPath("WEB-INF/" + filename);
System.out.println(path);
//获取文件类型
String mimeType = request.getServletContext().getMimeType(filename);
//将文件的类型告诉浏览器
// response.setHeader("conten-type",mimeType);
response.setContentType(mimeType);
//告诉浏览器以附件的形式来展示文件
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
//开启IO流进行下载
File file = new File(path);
if (file.exists()) {
//如果文件存在 我们就开始下载
//输入流
FileInputStream in = new FileInputStream(file);
//获取输出流
ServletOutputStream outputStream = response.getOutputStream();
//IO流拷贝
int len = 0;
byte[] arr = new byte[1024];
while ((len = in.read(arr)) != -1) {
outputStream.write(arr, 0, len);
}
in.close();
//response被销毁的时候被关闭
// outputStream.close();
}
}
}
}
5.3 Session销毁
方式一:时间超出了session的存活时间
session的默认存活时间是30分钟,在tomcat的全局配置文件web.xml中。(路径:tomcat/config/web.xml)
我们可以在web.xml中自己设置这个存活时间。我们设置的这个时间会覆盖原来的存活时间。
【注意】
注意:30分钟从什么时候开始计算?
从用户最后一次访问时间开始计算:
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。
注意:开发中一般我们将session设置为30分钟,所以没有必要对session的存活时间进行设置。这个知识点了解就好了。
【案例】手动配置session的存活时间
将session-config这段配置复制到自己项目中的web.xml中。修改存活时间为1,测试生存时间。
【web.xml配置】
1
提示:知识点了解即可,不需要掌握。
方式二:在Servlet中手动销毁
手动销毁session,调用的方法是:session.invalidate()方法;
package cn.itheima.session06;
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;
@WebServlet("/invalidateServlet")
public class InvalidateServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建session
HttpSession session1 = request.getSession();
System.out.println("session1被创建了。session1="+session1);
//手动销毁session
session1.invalidate();
System.out.println("session1被销毁了.......................");
//再次获取session
HttpSession session2 = request.getSession();
System.out.println("session2="+session2);
}
}
效果图:
方式三:服务器非正常关闭【了解】
如果正常关闭服务器,session的信息,会被序列化硬盘中,保存在tomcat的work\Catalina\localhost\web_day05,当tomcat下一次启动的时候,会把session加载回来。序列化的文件会被销毁。
5.4 浏览器关闭后,session持久化方案(重要)
通过上面的例子我们发现,浏览器关闭后,JSESSIONID就消失来,再次访问的时候又重新创建了一个新的session对象。这样,是比较消耗资源的。如何在浏览器关闭后,session能够继续存在呢?
答案:session之所以重新创建是因为,浏览器关闭后JESSIONID这个cookie消失了。所以,就不能够在标识这个session了。如果能够让cookie不消失(或者存活时间长点)就能够在很长一段时间内把这个标识发送给Servlet了。此时Servlet就能够找到之前创建的session对象了。
【实现方案】
1. 在Servlet中手动创建JESSIONID;
2. 手动设置JESSIONID的存活时间;
3. 将JESSIONID相应给浏览器;
【参考代码】
package cn.itheima.sessionchi07;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/chiServlet")
public class ChiServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//进行session持久化操作
//保证cookie名称 JSESSIONID 获取session的id
String id = request.getSession().getId();
Cookie cookie = new Cookie("JSESSIONID",id);
System.out.println("id = " + id);
//对cookie进行持久化操作
cookie.setMaxAge(60*30);
//cookie响应回浏览器
response.addCookie(cookie);
}
}
【运行结果】
关闭浏览器再次访问:http://localhost:8080/chiServlet
总结:因为cookie被我们持久化了,所以,即使用户再次关闭浏览器,都会一直访问到刚才的session中。不会再次创建session而消耗内存了。
session持久化很重要,要求大家掌握
7、Session综合案例(重要)
验证码校验案例
7.1 验证码校验
【验证码】
验证码是由计算机给浏览器端生成的一张图片,这张图片上有扭曲变形的数字或文字。扭曲变形是为了防止光学识别。这个问题是由计算机生成评判,必须由人类才能解答。所以,就能够有效防止某个黑客对某一个特定注册用户用特定程序暴力破解。
【验证码校验】
【生成验证码】使用GUI技术
package com.heima.web;
package com.itheima.cookie.checkcode;
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;
/**
* Created by tps on 2018/7/7.
*/
@WebServlet("/codeServlet")
public class CodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// gui 生成图片
// 1 高和宽
int height = 30;
int width = 60;
String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
// 2 创建一个图片
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 3 获得画板
Graphics g = image.getGraphics();
// 4 填充一个矩形
// * 设置颜色
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
g.setColor(Color.WHITE);
g.fillRect(1, 1, width - 2, height - 2);
// * 设置字体
g.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, 25));
StringBuffer sb = new StringBuffer();
// 5 写随机字
for (int i = 0; i < 4; i++) {
// 设置颜色--随机数
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 获得随机字
int index = random.nextInt(data.length());
String str = data.substring(index, index + 1);
// 写入
g.drawString(str, width / 6 * (i + 1), 20);
sb.append(str);// 获取验证码数据
}
// 验证码保存到session中
request.getSession().setAttribute("code",sb.toString());
// 6 干扰线
for (int i = 0; i < 3; i++) {
// 设置颜色--随机数
g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
// 随机绘制先
g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
// 随机点
g.drawOval(random.nextInt(width), random.nextInt(height), 2, 2);
}
// end 将图片响应给浏览器
ImageIO.write(image, "jpg", response.getOutputStream());
}
}
【页面引入验证码】
【验证码校验】
package com.heima.user.web;
import com.heima.user.bean.User;
import com.heima.user.service.UserService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
*@author buguniao
*/
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
//1、获取请求数据
String name = request.getParameter("name");
String password = request.getParameter("password");
String rememberMe = request.getParameter("rememberMe");
//获取验证码
String checkCode = request.getParameter("checkCode");
//封装数据
User user = new User();
user.setName(name);
user.setPassword(password);
//验证码校验
//1、获取session中的验证
String serverCode = (String) request.getSession().getAttribute("code");
if(!serverCode.equalsIgnoreCase(checkCode)){
//验证码错误
//登录失败 拼接login.html,并回显错误信息
request.setAttribute("errorMsg", "验证码错误!");
request.getRequestDispatcher("/loginErrorServlet").forward(request, response);
return;
}
//2、处理数据:登录业务逻辑
UserService userService = new UserService();
boolean loginFlag = userService.login(user);
//3、响应数据
if (loginFlag) {
//如果记住我复选框被勾选
if ("remember-me".equals(rememberMe)) {
//处理记住密码业务逻辑
Cookie nameCookie = new Cookie("name", name);
Cookie pwdCookie = new Cookie("password", password);
//将Cookie发送给浏览器
response.addCookie(nameCookie);
response.addCookie(pwdCookie);
}
//登录成功 重定向到成功页面
response.sendRedirect("/success.html");
} else {
//登录失败 拼接login.html,并回显错误信息
request.setAttribute("errorMsg", "用户名或密码错误!");
request.getRequestDispatcher("/loginErrorServlet").forward(request, response);
}
}
}
效果:
【验证码优化】
点击图片后,更新验证码
【第一步】给图片添加点击事件
【第二步】点击事件触发后,发送请求更新图片验证码
8、Servlet作用域总结
【API操作】操作三个作用域对象的API