什么是会话?
- 用户开一个浏览器,点击多个超链接,访问了同一个服务器的多个web资源,然后关闭浏览器,这样的过程称之为一个会话。
会话技术解决的核心问题——保存会话过程中产生的数据
- 每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自回产生一些数据,程序要想办法为每个用户保存这些数据。
- 无法使用context域或者request来保存数据,因为只存了商品没有存对应信息,context的话无法区分信息的归属,而request在多线程的使用场景下, 很难传递信息。
- 在tomcat中,也十几道多线程的使用场景:Servlet都是单实例,但是对于各个不同的请求,我们的tomcat实际上对每一个请求都创建一个新的线程,然后在新的线程中,调用service方法。
Cookie基本api
- javax.servlet.http.Cookie类用于创建一个Cookie,response接口中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类的方法:
- public Cookie(String name,String value)
- setValue与getValue方法
- setMaxAge与getMaxAge方法 (秒) 设置cookie的生命周期
- getName方法(cookie中的键值对中的键)
- 如何绝对每次请求在请求中携带哪些cookie信息呢?
根据本次请求的url,如果求的url
1.其域名和我浏览器中的cookie相同
2.同时,本次请求的URI部分,startwith cookie的path - 第二个问题,cookie是谁,设置的?
-
- Cookie的path和domain可以通过cookie的api可以自己设置
-
- 默认请况下,即我们在new出cookie对象之后,未显示设置cookie的domain 和path.浏览器在存储cookie对象的时候,会设置cookie的domain(域名) 和 path(路径).
-
- 浏览器,如何去设置domain和path的值呢?
-
- Domain就是产生这个cookie的servlet所在的服务器的域名
-
- Path就是产生这个cookie的servlet的全路径(http://localhost/haha/servletB)的URI部分中,最后一级路径父路径
-如果当前浏览器发出的请求中,并未携带任何cookie数据,此时,调用getCookies获取请求中所携带的cookie信息,返回值为null
- Path就是产生这个cookie的servlet的全路径(http://localhost/haha/servletB)的URI部分中,最后一级路径父路径
- 如何删除cookie?
1.从request中找到要删除的cookie
2.设置要删除的cookie的path(一定要和浏览器中存储的path一致,才会真正删除), setMaxAge(0)
3.将获取到的cookie,在修改其相应属性之后,将该cookie对象写回浏览器,让浏览器真正执行删除动作
如何显示用户上次访问的时间?
package haha;
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;
import java.util.Date;
@WebServlet(name = "ServletRequestLastTime2,urlPatterns = /servlet/ServletRecordLasttime")
public class ServletRequestLastTime2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
if (null==cookies){
//第一次访问
response.getWriter().write("您是第一次访问");
}else{
//当前浏览器请求时有携带cookie信息
Cookie last=null;
for (Cookie cookie:cookies
) {
if ("lastvisit".equals(cookie)){
last=cookie;
break;
}
}
if(null==last){
response.getWriter().write("您是第一次访问");
}else{
long l = Long.parseLong(last.getValue());
Date date = new Date(l);
response.getWriter().write("您上次访问时间"+date);
}
}
}
}
删除已经存在的cookie
package haha;
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(name = "ServletDeleteCookie, urlPatterns = /servlet/deletecookie")
public class ServletDeleteCookie extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//删除cookie
//找到那个要删除的cookie
Cookie[] cookies = request.getCookies();
if(null != cookies) {
//请求中有携带cookie信息
for (Cookie cookie : cookies) {
if("lastVisit".equals(cookie.getName())) {
//从浏览器所携带的所有cookie中,找到了我要删除的cookie
cookie.setPath("/");
//设置其过期时间, 0是马上过期
cookie.setMaxAge(0);
//将修改之后的cookie写回浏览器,让浏览器完成删除动作
response.addCookie(cookie);
}
}
}
}
}
1.从request中找到要删除的cookie
2.设置要删除的cookie的path(一定要和浏览器中存储的path一致,才会真正删除),并调用 setMaxAge(0)
3.将获取到的cookie,在修改其相应属性之后,将该cookie对象写回浏览器,让浏览器真正执行删除动作
- 浏览器默认给cookie设置的domain和path,在发送请求时是不会发送到服务器的,因此,服务器端拿到的domain和path都是null.即使设置了path,浏览器在请求时,也不会将path发送到服务器,因为这个path只有浏览器自己用。
Cookie细节
- 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(name)和值(value)value也必须是string类型。
- 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
- 浏览器一般只允许存放300个Cookie,每个站点最多存放20-50个Cookie,每个Cookie的大小限制为4KB。
- 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。注意,删除cookie时,path必须一致,否则不会删除
- 哪两个path一致呢? 一个是在浏览器中存储那个cookie的path,
另外一个是从request对象中查找到的我们要删除的request对象中的cookie对象的path
使用动态生成的网页
- 为什么要使用动态生成的网页?
- 因为使用静态网页的话很难与servlet互动,读取cookies等操作也无法进行
cookie demo模拟用户登录
当用户第二次登录时,用户名显示用户上个次登录的用户名
实现业务逻辑的servlet:
package haha;
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;
import java.util.List;
@WebServlet(name = "LoginServlet",urlPatterns = "/loginservlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("接收到登录请求了");
//1、首先接收一下,请求其中传递的用户名和密码,以及是否保存用户名的信息
String username = request.getParameter("username");
String password = request.getParameter("password");
String remember = request.getParameter("remember");
//2、验证一些请求中的用户名和密码能够登录,如果没有登录,跳转到登录页面
//获取已经注册的所有用户信息
List<User> allGegisterUser = UserDB.getAllGegisterUser();
//校验,当前请求中的用户名和密码是否已经注册过
boolean isLoginSuccess=false;
for (User user:allGegisterUser
) {
if (user.getUsername().equals(username)&&user.getPassword().equals(password)){
isLoginSuccess=true;
break;
}
}
if(isLoginSuccess){
//3、判断yoghurt是否选择保存自己的用户名,用户选择保存,用cookie保存用户用户名,返回登录成功信息,
// 如果用户没有选择保存,只需要返回登录成功信息,
if("checked".equals(remember)){
Cookie name = new Cookie("username", username);
response.addCookie(name);
}
response.getWriter().write("恭喜您登录成功");
}else{
request.getRequestDispatcher("/servletshowlogin");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
实现动态网页的servlet
package haha;
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(name = "ServletShowLogin",urlPatterns = "/servletshowlogin")
public class ServletShowLogin extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
String name="";
if (null!=cookies){
//浏览器的请求中有cookie,此时我们需要搜索,浏览器所携带的cookie中
//是否有username这个cookie
for (Cookie cookie:cookies
) {
if ("username".equals(cookie.getName()))
name=cookie.getValue();
break;
}
if(" ".equals(name)){
}
}
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Title</title>\n" +
"</head>\n" +
"<body>\n" +
"<form action=\"/haha/loginservlet\" method=\"post\">\n" +
" 用户名: <input type=\"text\" name=\"username\" value='"+name+"'><br>\n" +
" 密码: <input type=\"password\" name=\"password\"><br>\n" +
" 保存用户名:<input type=\"checkbox\"name=\"remember\" value=\"checked\"><br>\n" +
" <input type=\"submit\" value=\"登录\">\n" +
"</form>\n" +
"\n" +
"</body>\n" +
"</html>");
}
}
dataBase
package haha;
import javax.print.DocFlavor;
import java.util.ArrayList;
import java.util.List;
public class UserDB
{
private static List<User> db=new ArrayList<>();
static{
db.add(new User("zhangsan",1234+""));
db.add(new User("lisi",2345+""));
db.add(new User("wangwu",3456+""));
}
public static List<User> getAllGegisterUser(){
return db;
}
public static boolean judgeLogin(String name,String password){
for (User user : db) {
if(user.getUsername().equals(name) && user.getPassword().equals(password)) {
return true;
}
}
return false;
}
}
bean类
package haha;
public class User {
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;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
private String username;
private String password;
}
380

被折叠的 条评论
为什么被折叠?



