JavaWeb实验课---4.3cookie和session---2022.10

4.3 cookie-session

学习目标:

  1. 什么是Cookie和Session

  2. Cookie对象和Session对象的使用

  3. 购物车和用户登录的流程

  4. 会话概述
    案例:两个人打电话,你问我答。
    Web应用会话:一个用户在某网站上的整个购物过程就是一个会话

  • 一个客户端(浏览器)与Web服务器之间连续发生的一系列请求和响应过程。
  • Servlet技术中,提供了两个用于保存会话数据的对象,分别是Cookie和Session

2.1 什么是Cookie
Cookie的功能类似于会员卡,通过会员卡可以看到用户信息,用户的消费会累积到会员卡
Cookie在浏览器和服务器之间的传输:

  1. 第一次访问服务器,服务器增加SetCookie头字段,将Cookie信息发送给浏览器,并保存在客户端。
  2. 在后续访问服务器时,会在请求消息中将Cookie数据发送给服务器,从而使服务器分辨出当前请求是哪个用户发出的。

2.2 Cookie API

  1. 构造方法 Cookie(String name, String value)
  2. Cookie类的常用方法

4.3.1 响应消息中添加Cookie

目标

服务端通过response.addCookie(),浏览器端能看到(开发者工具:网络,应用,控制台)
目标:要能够在响应标头中看到Set-Cookie,第二次请求时,要在请求标头中看到Cookie,在应用中能看到Cookie具体属性

步骤:

  1. 创建setServletCookie.java文件,继承自HttpServlet
  2. 创建一个Cookie对象,参数为user、zhang3
  3. 配置URL,启动程序,打开对应网页

代码:

@WebServlet("/SetCookieServlet")
public class setCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("user","zhang3");
        resp.addCookie(cookie);
        resp.getWriter().append("Served at: ").append(req.getContextPath());
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

实验结果:

创建Cookie对象后,打开网址,响应标头中多了set-Cookie:user=zhang3,请求标头中也多了Cookie
请添加图片描述
在这里也可以看到Cookie的一些值
请添加图片描述

4.3.2 读取请求消息中的Cookie

目标:

服务端读取浏览器请求中的cookie并输出到控制台
第二次访问时,请求标头中有Cookie信息,要在服务器端把它获取出来,并且输出在页面上,或打印在控制台上

代码:

@WebServlet("/ReadCookiesServlet")
public class ReadCookiesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //getCookies会返回一个Cookie数组
        Cookie[] cookies = req.getCookies();
        //通过循环遍历,把这些信息输出在控制台上
        if(cookies != null){
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + "--->" + cookie.getValue());
            }
        }
        resp.getWriter().append("Served at: ").append(req.getContextPath());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

实验结果:

第二次请求时,浏览器把Cookie发送到了服务端,服务端收到了并输出
请添加图片描述

4.3.3 删除Cookie

目标

清除cookie

步骤:

  1. 在浏览器—检查元素—控制台处再添加一个cookie
  2. 新写一个ClearCookiesServlet.java,用来删掉cookie
  3. 打开ReadCookiesServlet网页,可以看到idea的控制台输出了当前cookie
  4. 打开ClearCookiesServlet网页,删除cookie
  5. 打开检查元素,在cookie中已经看不到user和pwd两个cookie的信息了

代码:

@WebServlet("/ClearCookiesServlet")
public class ClearCookiesServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            cookie.setMaxAge(0);    //删掉cookie
            resp.addCookie(cookie); //响应给浏览器
            System.out.println(cookie.getName() + "-->" + cookie.getValue());
        }
        resp.getWriter().append("Served at: ").append(req.getContextPath());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

实验结果:

在控制台处添加cookie
在这里插入图片描述
两个cookie都有了
在这里插入图片描述
控制台端也已输出两个cookie
在这里插入图片描述
打开ClearCookiesServlet网页,删除cookie
在这里插入图片描述

问题及解决办法:

问题:不会删除cookie
解决办法:
首先使用req.getCookies()方法拿到浏览器内的Cookie数组
再遍历Cookie数组,依次使用cookie.setMaxAge(0)删掉cookieresp.addCookie(cookie)响应给浏览器

4.3.4. cookie案例-显示上次访问时间

目标:

学会如何使用Cookie技术实现显示用户上次的访问时间的功能

步骤:

  1. 创建Servlet,通过Date输出当前系统时间
  2. 要显示上次访问时间,就把这个date放到浏览器端,让浏览器保存,下次请求时再把时间给带过来
  3. 要在浏览器端保存,就需要浏览器去更新cookie,把当前这次访问的时间记录到cookie当中,在下次请求时发过来。
  4. 配置映射信息,查看运行效果
  5. 解决空格乱码

代码

@WebServlet("/LastAccessServlet")
public class LastAccessServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	//正确拿到浏览器中的cookies数组
        Cookie[] cookies = req.getCookies();
        String cookieName = "lastAccess";
        String lastTime = null;
        String returnMsg;
        //如果cookies数组中有cookie的name参数 = “lastAccess”
        //那么就用lastTime字符串获取它的值,即上次访问时间
        if(cookies != null){
            for (Cookie cookie : cookies) {
                if(cookieName.equals(cookie.getName())){  //如果有上次访问时间
                    lastTime = cookie.getValue();
                    lastTime = URLDecoder.decode(lastTime);
                }
            }
        }
        //如果lastTime不为空,就输出上次访问时间
        //如果lastTime为空,就要告诉浏览器,这是你的首次访问
        if(lastTime == null){
            returnMsg = "first Access!";
        } else {
            returnMsg = "last Access at : " + lastTime;
        }
		//通过Date获得当前系统时间,使用字符串str接收时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        String str = sdf.format(new Date());
        
        //告诉浏览器更新访问时间
        Cookie cookie = new Cookie(cookieName, URLEncoder.encode(str));
        resp.addCookie(cookie);
        resp.getWriter().append(returnMsg);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

实验结果:

第一次访问,请求标头中没有cookie,响应中有

第二次访问,显示了上次访问的时间,请求中也有了cookie
在这里插入图片描述
解决了空格报异常的问题:
在这里插入图片描述

问题及解决办法

问题:Cookie中存在无效字符
在这里插入图片描述
解决办法:空格 改为 #
在这里插入图片描述
解决办法2:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd#HH:mm:ss");
        //告诉浏览器更新访问时间
        Cookie cookie = new Cookie(cookieName, sdf.format(new Date()));

改为:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        String str = sdf.format(new Date());
        //告诉浏览器更新访问时间
        Cookie cookie = new Cookie(cookieName, URLEncoder.encode(str));

给lastTime增加一个解码的lastTime = URLDecoder.decode(lastTime);

4.3.5.创建session-浏览器查看对应cookie-JSESSIONID

Seesion对象(讲解)

  1. 什么是Session?
  • Session技术就好比医院发放给病人的就医卡和医院为每个病人保留病历档案的过程。
    医生通过就医卡可以查到病人的就诊信息。
  • 当浏览器访问Web服务器时,Seevlet容器就会创建一个Session对象和ID属性。Sesiion对象就相当于病历档案,ID就相当于就医卡号。
    通常,Session借助Cookie技术来传递ID属性的。
    (Cookie数据保存在浏览器上,Session数据保存在服务器上)
  1. HttpSession API
  2. Session超时管理
    在一定时间内,如果某个客户端一直没有请求访问,那么,Web服务器会认为客户端已经结束请求,将对应的Session对象变成垃圾对象,并进行清除。反之,Web服务器会创建一个新的Session对象,并分配一个新的ID属性。
    会话时间在web.xml文件中设置。

目标:

生成一个Session对象,把数据在页面上呈现出来,在浏览器这端能看到cookie信息

代码:

@WebServlet("/SessionInfoServlet")
public class SessionInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        HttpSession session = req.getSession(true);
        if(session == null){
            writer.println("没有get到session对象");
            return;
        }
        writer.println("session id: " + session.getId());
        writer.println("session created at: " + session.getCreationTime());
        writer.println("session LastAccessedTime at: " + session.getLastAccessedTime());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

实验结果:

服务器在创建session时,每个session都有编号,服务器把session id以cookie的形式发给浏览器,浏览器收到后就保存起来。下次请求时,浏览器就把JSession id发给服务器。
创建时间created at,上次访问时间LastAccessedTime,每次刷新,创建时间不变,上次访问时间改变。
在这里插入图片描述

问题及解决办法

第一次访问时,中文乱码
在这里插入图片描述
解决中文乱码:
在doGet方法的最开始加一个句resp.setContentType("text/html;charset=utf-8");

4.3.6.给session添加数据-attribute

步骤:

  1. 在代码中写一个session
  2. 通过setAttribute方法,添加了两个数据
  3. 在另一个Servlet中,先获取这个session,然后再getAttribute方法读这两个数据
  4. 如果浏览器关掉,cookie就没有了,所以两个数据都为null了

代码:

@WebServlet("/SessionSetAttributeServlet")
public class SessionSetAttributeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        HttpSession session = req.getSession(true);

        session.setAttribute("user","zhang3");
        session.setAttribute("age","20");
        writer.println("session id: " + session.getId());
        writer.println("数据已设置");

        writer.append("Served at: ").append(req.getContextPath());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
@WebServlet("/SessionGetAttributeServlet")
public class SessionGetAttributeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        HttpSession session = req.getSession(true);

        writer.println("session id: " + session.getId());
        writer.println("session user: " + session.getAttribute("user"));
        writer.println("session age: " + session.getAttribute("age"));

        writer.append("Served at: ").append(req.getContextPath());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

实验结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.3.7.基于session的能保存状态的用户登陆案例

1. 目标与流程分析

  1. 用户通过浏览器,先请求一个静态资源:/login.html,这个页面呈现的就是账号框、密码框、提交按钮。
  2. 用户填写好后,点击提交,这个提交的action会提交到另外一个servlet/login,它负责验证账号密码。
  3. 如果登录成功,让它重定向到:/home,在这个页面要展示已登录账号的用户名、退出登录按钮。
  4. 如果验证失败,就重定向到表单:/login.html,去重新填写账号密码
  5. 如果用户没有登录,直接在浏览器中输入/home来访问,就要在servlet中查询当前用户登录的状态,如果是登录的就展示用户信息,如果没登录,告诉浏览器让它重定向到:/login.html
  6. 如果在/home页面点击了退出登录,浏览器发送退出登录请求:/logout
    总结:一个可登录的页面:/login.html/login负责验证,登录成功转到/home,当用户点击退出按钮,就访问servlet/logout,把登录信息删掉。
    登录状态用session来保存,在session中添加一个user数据,如果有这个user数据,我们就认为当前是登录状态,如果没有user数据,就认为它是非登录状态。

代码

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String pwd = req.getParameter("pwd");

        if ("123".equals(pwd)) {
            req.getSession().setAttribute("user", username);

            //如果登录成功,重定向跳转
            resp.sendRedirect("/ch0407_war_exploded/home");
        } else {
            //如果验证失败,重定向跳转到login.html
            resp.sendRedirect("/ch0407_war_exploded/login.html");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
@WebServlet("/home")
public class HomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码方式
        resp.setContentType("text/html;charset=utf-8");

        //判断用户是否在登录状态,如果不在登录状态,要重定向到login.html
        HttpSession session = req.getSession();
        //如果有session对象,并且session对象当中已经保存了user
        if (session != null && session.getAttribute("user") != null) {
            //展示信息
            resp.getWriter().append("<!DOCTYPE html>")
                    .append("<html lang=\"en\">")
                    .append("<head>")
                    .append("<meta charset=\"UTF-8\">")
                    .append("<title>Title</title>")
                    .append("</head>")
                    .append("<body>")
                    .append("<h1>管理首页</h1>")
                    .append("<h4>登录用户:" + session.getAttribute("user") + "</h4>")
                    .append("<a href='logout'>退出登录</a><br/>")
                    .append("添加成绩<br/>")
                    .append("修改成绩<br/>")
                    .append("....<br/>")
                    .append("</body>")
                    .append("</html>");
        } else {
            //重定向
            resp.sendRedirect("/ch0407_war_exploded/login.html");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //删除session中的数据
        if (req.getSession() != null) {
            req.getSession().removeAttribute("user");
        }
        //重定向到login.html
        resp.sendRedirect("/ch0407_war_exploded/login.html");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

实验结果:

访问home,重定向到login.html
两次请求,第一次请求home,它的响应是302、location
在这里插入图片描述
输入账号密码,如果密码错误,会重定向到login.html
在这里插入图片描述
登录成功后,跳转到home页面,显示用户信息
在这里插入图片描述
点击退出登录后,跳转到login.html,同时数据被删除。此时直接进home页面会重定向到login.html

问题及解决办法

用户名为中文时,home页面显示乱码
解决办法:
告诉tomcat,对方发过来的数据是utf-8的。req.setCharacterEncoding("utf-8");
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Web上开发一个网上蛋糕商城的前台,主要分为用户界面设计、交互功能实现和数据展示等几个关键部分。以下是前台开发的一般实验思路: 1. **需求分析**: - 确定商城的主要功能,如商品浏览、搜索、购物车管理、订单流程(添加、确认、支付)和用户登录注册等。 - 明确界面风格,如响应式设计以适应不同设备。 2. **界面设计**: - 使用HTML/CSS构建静态页面布局,包括导航栏、轮播图、商品列表页、详情页和用户个人中心等。 - 利用Bootstrap或其他前端框架进行快速样式搭建。 3. **JavaScript或jQuery**: - 实现动态效果,如图片轮播、下拉菜单、按钮点击事件处理等。 - 利用AJAX异步加载数据,提升用户体验,避免页面刷新。 4. **UI组件化**: - 使用前端框架提供的组件库,比如React、Vue或Angular,提高开发效率并保证代码复用。 5. **用户认证与权限管理**: - 使用session或JWT进行用户身份验证,确保用户只能访问自己的数据。 - 设计用户权限系统,如管理员能查看和修改所有数据,普通用户只能查看和购买。 6. **数据绑定和模型驱动**: - 如果使用MVVM架构,如Angular,利用双向数据绑定连接视图和模型。 7. **前端状态管理**: - 使用Redux或Vuex管理应用状态,保证状态的一致性和可预测性。 8. **SEO优化**: - 为搜索引擎优化考虑,确保页面元素有正确的元信息和结构。 9. **性能优化**: - 压缩和合并CSS/JS文件,减少HTTP请求。 - 利用CDN加速资源加载。 10. **测试**: - 编写单元测试和集成测试,确保各个功能正常工作。 - 进行用户验收测试,收集用户反馈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值