动态网站开发学习笔记04:动态网站会话及会话技术

一、会话概述

目标:了解会话的概念,能够知道会话用于做什么

在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话。在打电话过程中,通话双方会有通话内容,同样,在客户端与服务器交互的过程中,也会产生一些数据。例如,用户甲和乙分别登录了购物网站,甲购买了一个iPhone手机,乙购买了一个iPad,当这两个用户结账时,Web服务器需要对用户甲和乙的信息分别进行保存。为了保存会话过程中产生的数据,Servlet提供了两个用于保存会话数据的对象,分别是Cookie和Session。

二、Cookie案例演示 - 显示用户上次访问时间

1、创建Web项目

  • Web项目 - CookieDemo
    在这里插入图片描述
    在这里插入图片描述

2、修改Artifact名称,重新部署项目

在项目结构窗口里修改Artifact名称

在这里插入图片描述

  • 编辑服务器配置,重新部署项目,URL变成http://localhost:8080/CookieDemo/
  • 修改首页
  • 启动服务器,查看效果
    在这里插入图片描述

3、创建LastAccessServlet类

创建net.xyx.servlet包,然后在里面创建LastAccessServlet类

在这里插入图片描述

package net.xyx.servlet;

import jdk.nashorn.internal.ir.CallNode;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet(name = "LastAccessServlet", value = "/LastAccessServlet")
public class LastAccessServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应对象内容类型(网页、编码),避免中文乱码
        response.setContentType("text/html; charset=utf-8");
        //打印输出流
        PrintWriter out = response.getWriter();
        //获取所有cookie
        Cookie[] cookies = request.getCookies();
        //定义标志变量isFirstAccess
        boolean isFirsetAccess = true;
        //判断cookies是否为空
        if (cookies.length > 0 && cookies != null){
            //遍历cookies数组
            for (Cookie cookie : cookies){
                //获取cookie的名称
                String name = cookie.getName();
                //判断cookie名称是否为“lastTime”
                if (name.equals("lastTime")){
                    //用户不是第一次访问
                    isFirsetAccess = false;
                    //获取cookie的值(上次访问时间)
                    String value = cookie.getValue();
                    //控制台输出解码的数据
                    System.out.println("解码前:" + value);
                    //对cookie值进行URL解码
                    value = URLDecoder.decode(value,"utf-8");
                    //控制台输出解码后的数据
                    System.out.println("解码后" + value);
                    //在页面显示用户上次访问时间
                    out.print("欢迎回来,您上次访问时间" + value);
                    //获取当前时间字符串,重新设置cookie
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String strDate = sdf.format(date);
                    //控制台输出编码前的日期数据
                    System.out.println("编码前:" + strDate);
                    //对日期数据进行URL编码
                    strDate = URLEncoder.encode(strDate,"utf-8");
                    //控制台输出编码后的日期数据
                    System.out.println("编码后:" + strDate);
                    //设置cookie的值
                    cookie.setValue(strDate);
                    //设置cookie的存储时间(以秒为单位)
                    cookie.setMaxAge(30*24*60*60);//一个月
                    //加入cookie,让其生效
                    response.addCookie(cookie);
                }
            }
        }if (isFirsetAccess){//cookie为空,表明是第一次访问
            //获取当前时间字符串,重新设置cookie
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String strDate = sdf.format(date);
            //控制台输出编码前的日期数据
            System.out.println("编码前:" + strDate);
            //对日期数据进行URL编码
            strDate = URLEncoder.encode(strDate,"utf-8");
            //控制台输出编码后的日期数据
            System.out.println("编码后:" + strDate);
            //创建一个cookie
            Cookie cookie = new Cookie("lastTime", strDate);
            //设置cookie的值
            cookie.setValue(strDate);
            //设置cookie的存储时间(以秒为单位)
            cookie.setMaxAge(30*24*60*60);//一个月
            //加入cookie,让其生效
            response.addCookie(cookie);
            //在页面显示欢迎用户首次访问信息
            out.print("您好,欢迎您首次访问本网站~");
        }
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
            throws javax.servlet.ServletException, IOException {
        doPost(request,response);

    }
}

在这里插入图片描述

三、Session案例演示 - 实现购物车

目标:使用Session相关知识,实现模拟购物车的功能

1、创建蛋糕实体类

  • 创建SessionDemo项目
    在这里插入图片描述
    在这里插入图片描述

  • 编辑首页
    在这里插入图片描述

  • 创建net.xyx.session.bean包,然后在包里创建Cake类
    在这里插入图片描述

package net.xyx.session.bean;

public class Cake {
    private  String id;
    private String name;

    public Cake(){

    }

    public Cake(String id, String name){
        this.id = id;
        this.name = name;
    }

    public String getId(){
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2、创建蛋糕数据访问对象

在这里插入图片描述

package net.xyx.session.dao;

import net.xyx.session.bean.Cake;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

public class CakeDao {
    private static Map<String, Cake> cakes = new LinkedHashMap<>();

    static {
        cakes.put("1",new Cake ("1","A类蛋糕"));
        cakes.put("2",new Cake ("2","B类蛋糕"));
        cakes.put("3",new Cake ("3","C类蛋糕"));
        cakes.put("4",new Cake ("4","D类蛋糕"));
        cakes.put("5",new Cake ("5","E类蛋糕"));
    }
    //获取所有数据
    public static Collection<Cake> findAllCakes(){
        return cakes.values();
    }

    //按编号获取蛋糕
    public static Cake findCakeById(String id){
        return cakes.get(id);
    }
}

3、创建蛋糕列表处理程序

创建net.xyx.session.servlet包,然后在包里创建CakeListServlet类,用于显示所有可购买蛋糕的列表,通过单击“购买”链接,便可将指定的蛋糕添加到购物车中
在这里插入图片描述

在这里插入图片描述

4、创建购物处理程序

在net.xyx.session.servlet包里创建PurchaseServlet类
在这里插入图片描述

package net.xyx.session.servlet;

import net.xyx.session.bean.Cake;
import net.xyx.session.dao.CakeDao;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet(name = "PurchaseServlet")
public class PurchaseServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

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

//获取用户购买蛋糕的id
        String id = request.getParameter("id");
        //判断用户是否选购
        if(id != null){
            //按照id获取蛋糕对象
            Cake cake = CakeDao.findCakeById(id);
            // 创建或者获得用户的Session对象
            HttpSession session = request.getSession();
            // 从Session对象中获得用户的购物车
            List<Cake> cart = (List) session.getAttribute("cart");
            if (cart == null) { // // 首次购买
                // 为用户创建一个购物车(List集合模拟购物车)
                cart = new ArrayList<Cake>();
                // 将购物城存入Session对象
                session.setAttribute("cart", cart);
            }
            // 将商品放入购物车
            cart.add(cake);
            // 创建Cookie存放Session的标识号
            Cookie cookie = new Cookie("JSESSIONID", session.getId());
            cookie.setMaxAge(60 * 30);
            cookie.setPath("/Servlet");
            response.addCookie(cookie);
            // 重定向到购物车页面(CartServlet)
            response.sendRedirect("cart");

        } else {
            // 重定向到蛋糕列表显示页面(CakeListServlet)
            response.sendRedirect("cake_list");
        }
    }
}

5、创建购物车处理程序

在net.xyx.session.servlet包里创建CartServlet类
在这里插入图片描述

package net.xyx.session.servlet;

import net.xyx.session.bean.Cake;

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.io.PrintWriter;
import java.util.List;

@WebServlet(name = "CartServlet")
public class CartServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 变量cart引用用户的购物车
        List<Cake> cart = null;
        // 变量hasPurchased标记用户是否买过商品
        boolean hasPurchased = true;
        // 获得用户的session
        HttpSession session = request.getSession(false);
        // 判断会话是否为空
        if (session == null) { // 尚未购买过商品
            hasPurchased = false;
        } else {
            // 获得用户购物车
            cart = (List) session.getAttribute("cart");
            // 判断购物车是否为空
            if (cart == null) { // 尚未购买过商品
                hasPurchased = false;
            }
        }

        out.print("<body style='text-align: center'>");
        // 判断用户是否购买过商品
        if (!hasPurchased) {
            out.print("遗憾,您尚未购买任何商品~<br>");
        } else {
            // 显示用户购买蛋糕的信息
            out.print("<h3>您购买的蛋糕</h3>");
            for (Cake cake : cart) {
                out.print(cake.getId() + " " + cake.getName() + "<br>");
            }
        }

    }

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

    }
}

6、随后可以运行程序查看效果