Web开发会话技术(Cookie,Session)
Cookie
-
Cookie是服务器在客户端保存用户的信息,比如登录名,浏览历史等,就可以以cookie方式保存.
-
Cookie信息就像是小甜饼(cookie中文)一样,数据量并不大,服务器端在需要的时候可以从客户端/浏览器读取(http协议)
-
JSESSIONID是用来标识每一次会话的,是不同会话的唯一标识
-
创建Cookie对象,发送到浏览器
- 先创建一个Cookie对象
- 再将Cookie对象加入的http的响应对象resp中
package com.hspedu.cookie_session;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* @Projectname: servlet
* @Filename: CreateCookie
* @Author: 杨逸
* @Data:2023/4/8 11:01
* @Description: TODO
*/
public class CreateCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个Cookie
/**
* cookieName是该Cookie对象的名称,是唯一的,不能重复,重复会覆盖上一个
* cookieValue是该Cookie的值
* 可以同时创建多个Cookie
*/
Cookie cookie = new Cookie("cookieName", "cookieValue");
resp.setContentType("text/html;charset=utf-8");
//将Cookie放入http响应发送给浏览器
resp.addCookie(cookie);
PrintWriter writer = resp.getWriter();
writer.print("<h1>创建Cookie成功</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- 读取浏览器发送的Cookie
- 先从http的请求对象中获得存放所有的Cookie的数组
- 再遍历存放Cookie的数组得到Cookie
package com.hspedu.cookie_session;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* @Projectname: servlet
* @Filename: ReadCookie
* @Author: 杨逸
* @Data:2023/4/8 11:19
* @Description: TODO
*/
public class ReadCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//读取http请求发送过来的Cookie
//获得http发送的所有Cookie
Cookie[] cookies = req.getCookies();
//判断,遍历
if (cookies != null && cookies.length != 0){
for (Cookie cookie :cookies) {
System.out.println("Cookie的名字" + cookie.getName() + "Cookie的值" + cookie.getValue());
}
}
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.print("<h1>Cookie读取成功</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- Cookie的修改
package com.hspedu.cookie_session;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* @Projectname: servlet
* @Filename: UpdateCookie
* @Author: 杨逸
* @Data:2023/4/8 11:49
* @Description: TODO
*/
public class UpdateCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//修改Cookie的值
//获得存放Cookie的数组
Cookie[] cookies = req.getCookies();
//获得指定名称的Cookie
Cookie cookieName = CookieUtils.getCookieByName("cookieName", cookies);
if (cookieName != null){
//如果找到指定的Cookie就修改
cookieName.setValue("updateCookieOfValue");
//修改后在加入到http响应对象resp中
resp.addCookie(cookieName);
}else {
//如果没找到指定的Cookie,就打印没有找到
System.out.println("没有指定的Cookie");
}
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.print("<h1>Cookie修改</h1>");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- Cookie的生命周期
{
//创建一个Cookie,使用setMaxAge()方法设置生命周期
//默认是-1,即浏览器退出后该Cookie就不生效
//0表示浏览器接收到该Cookie后,马上就失效了
//设置具体的数字n,表示浏览器接收到该Cookie后n秒后,该Cookie才失效
Cookie cookie = new Cookie("job", "java");
//设置该Cookie60秒后过期
cookie.setMaxAge(60);
}
- Cookie的有效路径
- Cookie的path属性可以有效的过滤哪些Cookie可以发送给服务器。哪些不发。path属性是通过请求的地址
来进行有效的过滤 - 规则如下:
- cookie1.setPath=/工程路径
- cookie2.setPath=/工程路径/aaa
- 请求地址:http://ip:端口/工程路径/资源
- cookie1会发给服务器
- cookie2不会发给服务器
- 请求地址:http://ip:端口/工程路径/aaa/资源
- cookie1和cookie2都会发给服务器
- 请求地址:http://ip:端口/工程路径/资源
- Cookie的默认有效路径是项目的工程路径
- 通过控制Cookie的有效路径,可以控制浏览器在访问哪些资源时可以发送服务器需要的Cookie
- Cookie的path属性可以有效的过滤哪些Cookie可以发送给服务器。哪些不发。path属性是通过请求的地址
//设置Cookie的路径
Cookie cookie = new Cookie("name1", "value1");
Cookie cookie1 = new Cookie("name2", "value2");
//开始设置不同的有效路径
cookie.setPath(getServletContext().getContextPath());
cookie1.setPath(getServletContext().getContextPath() + "/aaa");
- 使用Cookie实现自动填用户信息
- 使用两个Servlet,一个用于展示页面,一个用于处理登陆请求
- 展示页面Servlet通过获得Cookie信息决定页面然后展示
- 登陆处理Servlet通过表单提交的信息设置Cookie信息
//用于展示页面的Servlet
package com.hspedu.cookie_session;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* @Projectname: servlet
* @Filename: HomeworkCookie
* @Author: 杨逸
* @Data:2023/4/8 15:24
* @Description: Cookie的作业
* 使用Cookie实现自动填写用户名
*/
public class HomeworkCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//先获得Cookie
Cookie[] cookies = req.getCookies();
//获得标记自动填写用户名的Cookie
Cookie keepCookie = CookieUtils.getCookieByName("KeepLogin", cookies);
//设置返回的格式和编码
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
//判断是否要自动填写
if (keepCookie != null && "1".equals(keepCookie.getValue())){
//自动填写用户名
Cookie username = CookieUtils.getCookieByName("username",cookies);
if (username != null){
//用于登陆的html
String meg = "<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <base href=\"/servlet/\">\n" +
" <title>登陆</title>\n" +
"</head>\n" +
"<body>\n" +
"<form action=\"login\" method=\"post\">\n" +
" 用户名<input type=\"text\" name=\"username\" value=\""+username.getValue()+"\"><br>\n" +
" 密 码<input type=\"password\" name=\"password\"><br>\n" +
" <input type=\"submit\" value=\"提交\">\n" +
"</form>\n" +
"</body>\n" +
"</html>";
writer.print(meg);
}
}else {
String meg = "<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <base href=\"/servlet/\">\n" +
" <title>登陆</title>\n" +
"</head>\n" +
"<body>\n" +
"<form action=\"login\" method=\"post\">\n" +
" 用户名<input type=\"text\" name=\"username\"><br>\n" +
" 密 码<input type=\"password\" name=\"password\"><br>\n" +
" <input type=\"submit\" value=\"提交\">\n" +
"</form>\n" +
"</body>\n" +
"</html>";
writer.print(meg);
}
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
//用于处理登陆的Servlet
package com.hspedu.cookie_session;
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 java.io.IOException;
import java.io.PrintWriter;
/**
* @Projectname: servlet
* @Filename: LoginServlet
* @Author: 杨逸
* @Data:2023/4/8 15:31
* @Description: 登陆的servlet
*/
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得登陆表单提交的信息
String username = req.getParameter("username");
String password = req.getParameter("password");
//创建一个保存用户名的Cookie
Cookie cookie1 = new Cookie("username", username);
resp.addCookie(cookie1);
//判断密码是否正确
if ("123456".equals(password)){
//如果正确就创建一个标记自动填写用户名的Cookie返回
Cookie cookie = new Cookie("KeepLogin", "1");
resp.addCookie(cookie);
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.print("<h1>登陆成功!</h1>");
}else {
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.print("<h1>密码或用户名错误,登陆成功失败!</h1>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- Cookie注意事项和细节
-
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(
VALUE)。 -
一个WEB站点可以给一个浏览器发送多个Cookie,一个浏览器也可以存储多个WEB站点提供的
Cookie。 -
Cookie的总数量没有限制,但是每个域名的COOKIE数量和每个COOKIE的大小是有限制的
(不同的浏览器限制不同,知道即可),Cookie不适合存放数据量大的信息。 -
注意,删除Cookie时,path必须一致,否则不会删除
-
Java servlet中Cookie中文乱码解决
-
Cookie中使用中文默认是会报错的
-
可以使用URl编码后再存放
-
读取是先对数据进URl解码,就是正常的中文
//使用URLEncoder类对中文进行编码 String s = URLEncoder.encode("中文", "utf-8"); //编码后再放入到Cookie中就不会报错 //使用RULDecoder类对编码后的字符串进行解码 String decode = URLDecoder.decode(s, "utf-8"); //解码后就是正常的内容了
-
Session
- Session是服务器端技术,服务器在运行时为每一个用户的浏览器创建一个其独享的session对象/集合
- 由于session为各个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自的session中读取/添
加数据,从而完成相应任务 - 创建Session对象是通过HttpServletRequest对象的getSession()方法获得的
- 当Cookie中存在JSESSIONID时,查看Tomcat容器中是否存在该ID的Session对象
- 如果有就直接返回,如果没有就创建再返回
- 当Cookie中没有JSESSIONID时,就先获得JSESSIONID,返回给浏览器,然后再创建Session对象
- Session对象的常用方法
- 设置Session的属性,属性的名称是字符串类型,属性的值是Object对象类型,setAttribute("SessionName","SessionValue");
- 获得Session的属性,getAttribute("SessionName")
- 删除Session的属性,removeAttribute("SessionName")
- 获得Session的JSESSIONID(就是用户的唯一标识),getId()
- 设置Session的生命周期,单位秒(s),setMaxInactiveInterval(60)
- 没有参数,就是Tomcat中的配置的生命周期,默认是30分钟
- 参数是负数时,表示永不过期
- 参数为零时,表示马上过期
- 参数为正数时,表示过期时间的倒计时
- 获得Session的过期时间,getMaxInactiveInterval()
- 调用方法使当前Session立即无效,invalidate()
- Session的生命周期指的是:客户端两次请求最大间隔时长,而不是累积时长。即当客户端访问了自己的
session,session的生命周期将从0开始重新计算。(指的是同一个会话两次请求之间的间隔时间)- 底层:Tomcat用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁
package com.hspedu.cookie_session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @Projectname: servlet
* @Filename: GetSession
* @Author: 杨逸
* @Data:2023/4/8 18:08
* @Description: 获得session对象
*/
public class GetSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得Session对象,通过HttpServletRequest对象创建(获得)Session对象
//当Cookie中存在JSESSIONID时,查看Tomcat容器中是否存在该ID的Session对象,
// 如果有就直接返回,如果没有就创建再返回
//当Cookie中没有JSESSIONID时,就先获得JSESSIONID,返回给浏览器,然后再创建Session对象
HttpSession session = req.getSession();
//设置Session的属性
//属性的名称是字符串类型,属性的值是Object对象类型
session.setAttribute("SessionName","SessionValue");
//获得Session的属性
Object name = session.getAttribute("SessionName");
System.out.println("session的值" + name);
//删除Session的属性
session.removeAttribute("SessionName");
//设置Session的生命周期,单位秒(s)
session.setMaxInactiveInterval(60);
//获得Session的过期时间
int maxInactiveInterval = session.getMaxInactiveInterval();
//调用方法使当前Session立即无效
session.invalidate();
//获得Session的JSESSIONID(就是用户的唯一标识)
String id = session.getId();
System.out.println("session的JSESSIONID=" + id );
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- 使用Session实现管理页面访问控制(Session作业)
- 没有登陆成功时,直接访问管理页面会跳转到登陆失败页面
- 只有登陆成功时访问管理页面,管理页面的Servlet才会返回信息
- 使用两个Servlet实现,一个检查表单提交的参数,一个检查当前访问是否成功登陆
- 检查表单的Servlet
//检查表单的Servlet
package com.hspedu.cookie_session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @Projectname: servlet
* @Filename: LoginCheckServlet
* @Author: 杨逸
* @Data:2023/4/8 18:57
* @Description: Session的登陆检查Servlet
*/
public class LoginCheckServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得表单提交的数据
String password = req.getParameter("password");
//判断
if ("666666".equals(password)){
//如果密码通过,就创建一个Session
HttpSession session = req.getSession();
//给Session设置,允许访问登陆成功页面
session.setAttribute("login","1");
//然后转发到登陆成功管理Servlet
resp.sendRedirect("sessionManageLogin");
System.out.println("转发到登陆管理Servlet");
}else {
//如果密码没有通过,就转发到登陆失败页面
resp.sendRedirect("html/sessionLoginError.html");
System.out.println("转发到登陆失败页面");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- 控制页面访问的Servlet
//控制页面访问的Servlet
package com.hspedu.cookie_session;
import javax.servlet.ServletException;
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.io.PrintWriter;
/**
* @Projectname: servlet
* @Filename: SessionManageLogin
* @Author: 杨逸
* @Data:2023/4/8 19:11
* @Description: Session登陆成功页面的管理Servlet
*/
public class SessionManageLogin extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得请求的Session对象
HttpSession session = req.getSession();
//获得允许访问的属性
Object login = session.getAttribute("login");
//判断是否能访问该页面
if ("1".equals(login)){
//能访问,返回登陆成功页面
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
String meg = "<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <base href=\"/servlet/\">\n" +
" <title>session登陆成功页面</title>\n" +
"</head>\n" +
"<body>\n" +
"<h1>session登陆成功页面</h1>\n" +
"</body>\n" +
"</html>";
writer.print(meg);
writer.flush();
writer.close();
System.out.println("登陆成功");
}else {
//不能访问,转发到登陆失败页面
resp.sendRedirect("html/sessionLoginError.html");
System.out.println("登陆失败");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
- 登陆表单html和登陆失败的页面
//登陆表单html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/servlet/">
<title>sessionLogin</title>
</head>
<body>
<form action="loginCheckServlet" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
//登陆失败的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="/servlet/">
<title>session登陆失败页面</title>
</head>
<body>
<h1>登陆失败</h1>
<a href="html/sessionLogin.html">重新登录</a>
</body>
</html>