会话管理和使用以及页面展示的效果

  1. HTTP协议概述

HTTP是超文本传输协议的英文缩写,是基于TCP/IP通讯协议之上用来传输HTML和图片文件的应用协议,原本是用来从万维网服务器传输超文本到本地浏测览器。它是一个应用层面向对象的协议,优点是简捷、快速,适用于分布式超媒体信息系统。于1990年提出,经过多年的完善和扩展已经非常地成熟。HTTP协议主要工作于B-S架构之上,这个时候浏览器作为HTTP的客户端通过URL向HTTP的服务器(web服务器)发送所有请求,web服务器根据接收到的请求后,向客户端发送响应信息,客户端向服务器请求发送时,需要传送请求方法和路径。路径就是URL,而HTTP常用的请求方法为GET和POST方法,每种方法规定了客户端与服务器通讯方式和数据报文。

HTTP协议报文

客户端与服务器的通讯都是通过一个个请求来实现的,一个HTTP请求的消息包括:请求行、请求头部、空行、请求数据四个部分组成的。

服务器收到请求后,需要响应,而响应的消息也由四个部分组成:状态行、消息报头、空行、响应正文。

http报文总是向下游流动的。对于客户端而言,代理和服务器就是它的下游,请求报文会流向代理,然后在流向服务器;对于服务器而言,代理和客户端就是它的下游,报文会流向代理和客户端。如图所示:

网络协议:

网络协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则。

HTTP协议:

HTTP协议(超文本传输协议)是一种网络通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。默认端口:80

HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传送协议。

浏览器和服务器之间使用的是HTTP请求来进行数据传输
HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求
HTTP协议设计成无状态的目的是让每次请求之间相互独立,互不影响
请求与请求之间独立后,就无法实现多次请求之间的数据共享

工作过程:当我们在浏览器输入一个网址,此时浏览器就会给对应的服务器发送一个 HTTP 请求,对应的服务器收到这个请求之后,经过计算处理,就会返回一个 HTTP 响应。并且当我们访问一个网站时,可能涉及不止一次的 HTTP 请求和响应的交互过程。

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。

从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了
会话被建立后,如果浏览器或服务端都没有被关闭,则会话就会持续建立着
浏览器和服务器就可以继续使用该会话进行请求发送和响应,上述的整个过程就被称之为会话。
客户端会话跟踪技术:Cookie存储在浏览器端
服务端会话跟踪技术:Session存储在服务器端

请求报文格式:

<method> <request-URL> <version>
<headers>
<entity-body>

响应报文格式

<version> <status> <reason-phrase>
<headers>
<entity-body>

请求报文和响应报文的格式基本一致,它们只有起始行的语法有所不同。下面对请求报文和响应报文中各部分做一个描述。

起始行

所有的 HTTP 报文都以一个起始行作为开始。请求报文的起始行说明了要做些什么。响应报文的起始行说明发生了什么。

  • 请求行

请求行包括了方法,url,以及http协议版本。这三个字段之间由空格符分隔。例如:

  POST /api/post HTTP/1.1

这表示请求方法为 POST,请求 URL 为 /api/post,http协议的版本为1.1;请求方法用来告知服务器要做些什么,url是用来定位资源的位置,http版本将自己所遵循的协议版本告知对方,以便互相了解对方的能力和报文格式。

  • 响应行

响应行包括了http协议版本,响应状态码以及原因短语。这三个字段之间由空格符分隔,例如:

  HTTP/1.1 200 OK

这表示http版本是1.1,响应状态码是200,原因短语是OK。响应状态码的作用是告诉客户端,发生了什么事情,而原因短语是为了更便于人们理解,所有的处理过程使用的都是响应状态码。

方法

方法用来告诉服务器执行什么动作,主要是http的设计者们把一切都抽象为资源,而方法就是对资源执行的动作。如果一台服务器要与 HTTP 1.1 兼容,那么只要为其资源实现 GET 方法和 HEAD 方法就可以了。http提供了一些方法,即使服务器实现了所有这些方法,某些方法的使用很可能也是受限的,这些是可以通过在服务器的配置中进行设置的。例如有的服务器只允许get,head,options以及post请求。

另外就是HTTP方法在报文中必须是大写的。

安全方法

HTTP 定义了一组被称为安全方法的方法。GET 方法和 HEAD 方法都被认为是安全的,这就意味着使用 GET 或 HEAD 方法的 HTTP 请求不会在服务器上产生修改资源的操作。但是这并不是一定的,因为web开发者也可以让GET方法修改资源,这是由开发者决定的。通常大多数开发者都是开发RESTful风格的api,GET方法不会产生修改资源的效果。

HTTP常见方法表

http方法

作用

GET

GET 是最常用的方法。通常用于请求服务器发送某个资源。HTTP/1.1 要求服务器实现此方法。通常用在获取资源的场景下。

HEAD

HEAD 方法与 GET 方法的行为很类似,但服务器在响应中只返回首部。不会返回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。服务器开发者必须确保返回的首部与 GET 请求所返回的首部完全相同。遵循HTTP/1.1 规范,就必须实现 HEAD 方法。

PUT

PUT 方法的语义就是让服务器用请求的主体部分来创建一个由所请求的 URL 命名的新文档,或者,如果那个 URL 已经存在的话,就用这个主体来替代它。通常用在修改资源的场景下。

POST

POST 方法是用来向服务器输入数据的,通常在新增资源的场景下使用。

TRACE

客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的 HTTP 请求。TRACE 方法允许客户端在最终将请求发送给服务器时,看看它变成了什么样子。TRACE 方法主要用于诊断;也就是说,用于验证请求是否如愿穿过了请求或者响应链。它也是一种很好的工具,可以用来查看代理和其他应用程序对用户请求所产生效果。TRACE 请求中不能带有实体的主体部分。TRACE 响应的实体主体部分包含了响应服务器收到的请求的精确副本。

OPTIONS

OPTIONS 方法请求 Web 服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。这为客户端应用程序提供了一种手段,使其不用实际访问那些资源就能判定访问各种资源的最优方式。

DELETE

DELETE 方法所做的事情就是请服务器删除请求 URL 所指定的资源。但是,客户端应用程序无法保证删除操作一定会被执行。因为 HTTP 规范允许服务器在不通知客户端的情况下撤销请求

下图是trace请求的示例。

HTTP 被设计成字段可扩展的,这样新的特性就不会使老的软件失效了。扩展方法指的就是没有在 HTTP/1.1 规范中定义的方法。服务器会为它所管理的资源实现一些 HTTP 服务,这些方法为开发者提供了一种扩展这些 HTTP 服务能力的手段。通常情况下,我们是不会使用扩展方法的。

session详解

session在网络应用中称为“会话控制”,是服务器为了保存用户状态而创建的一个特殊的对象。简而言之,session就是一个对象,用于存储信息。

服务器会给每一个用户(浏览器)创建一个Session对象

比如我们现在都去访问百度,我们使用双核浏览器和谷歌浏览器同时访问百度这个网址,百度那边会有两个session,因为浏览器不一样,但是只要在一个浏览器里面一直用百度的话,就没有区别。我们用两个浏览器相当于是模拟两个客户端。

  1. 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在。

  1. 用户登录之后,整个网站它都可以访问。(保存用户的信息、保存购物车的信息)

比如我们登录csdn之后,csdn网站上的内容都可以进行点击,不用重复登录。可以访问该用户权限下的所有网页。

如果退出用户之后,其中的好多页面都需要我们进行登录之后才可以使用。

session的存储

session类似于一个Map,里面可以存放多个键值对,是以key-value进行存放的。key必须是一个字符串,value是一个对象。

session底层原理

session是每一个游览器(客户端)所唯一的,其实,在访问一个网站时,在HTTP请求中往往会携带一个cookie,这个cookie的名字是JSESSIONID,这个JSESSIONID表示的就是session的id,这个是由服务器创建的,并且是唯一的。服务器在使用session时,会根据JSESSIONID来进行不同操作。

session常用方法

  • resquest.getSession():得到请求游览器(客户端)对应的session。如果没有,那么就创建应该新的session。如果有那么就返回对应的session

  • setAttribute(String s, Object o):在session存放属性

  • getAttribute(String s):从session中得到s所对应的属性

  • removeAttribute(String s):从session中删除s对应的属性

  • getId():得到session所对应的id

  • invalidate():使session立即无效

  • setMaxInactiveInterval(int i):设置session最大的有效时间。

JSTL标签

JSTL(JavaServer Pages Standard Tag Library,JSP标准标签库)是一个JSP标签集合,它封装了JSP应用的通用核心功能。

在JSP文件开头使用

<!--在页面导入jstl的核心类库 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

EL表达式

Expression Language 表达式语言,常用于取值。

EL表达式是通过$ {} 从作用域对象中自动获取数据,如果是对象可以通过,访问其属性

<h2>欢迎来自${user.address}的${user.username}来到主页!</h2>

EL表达式多用于取值操作,而JSTL则可以方便我们对集合进行遍历,对数据进行判断等操作。


补充需求:

  1. 请求转发

2.把商品信息传输到页面中进行展示

此次项目步骤

登陆注册完成后,使用session的方法和JSTL标签和EL表达式完成需求;

Goods实体类(商品表)

package com.zhao.bean;

public class Goods {
    private Integer gid;
    private String gname;
    private String price;
    private String mark;

    public Goods() {
    }

    public Integer getGid() {
        return gid;
    }

    public void setGid(Integer gid) {
        this.gid = gid;
    }

    public String getGname() {
        return gname;
    }

    public void setGname(String gname) {
        this.gname = gname;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getMark() {
        return mark;
    }

    public void setMark(String mark) {
        this.mark = mark;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "gid=" + gid +
                ", gname='" + gname + '\'' +
                ", price=" + price +
                ", mark='" + mark + '\'' +
                '}'+"\n";
    }
}

login.java页面 (存储信息,转发请求)

package com.zhao.servlet;

import com.zhao.Dao.GoodsDao;
import com.zhao.Dao.UserDao;
import com.zhao.Dao.impl.UserDaoImpl;
import com.zhao.bean.Goods;
import com.zhao.bean.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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

public class Login extends HttpServlet {


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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置请求和响应的编码
        request.setCharacterEncoding("utf-8");//设置请求的编码
        response.setCharacterEncoding("utf-8");//设置响应的编码
//        response.setContentType("text/html;charset=UTF-8");//设置响应的文本格式和编码

        //2.获取请求参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
//        System.out.println(username);
//        System.out.println(password);

        //3.业务处理--JDBC操作
        UserDao userDao=new UserDaoImpl();
        User login = userDao.login(username, password);
        //4.判断业务处理结果,给前端做出响应
        if (login!= null) {
            System.out.println("登录成功");
            //1.登陆成功后,在session中保存用户的个人信息
            HttpSession session=request.getSession();
            session.setAttribute("user",login);
//            GoodsDao goodsDao=new GoodsDao();
//            List<Goods> goodsList=goodsDao.selectAll();
//            System.out.println(goodsList);
//            //登录成功
//            response.sendRedirect("zhuye.jsp");

            //请求转发---登录业务已经处理完毕,应该做请求转发,让别的servlet执行商品信息的查询
            request.getRequestDispatcher("selectAllGoods").forward(request,response);

        } else {
            //登录失败
            response.sendRedirect("error.jsp");
        }
    }
}

GoodsDao.java页面(JDBC查询并把数据存储到Goods对象再添加到集合中)

package com.zhao.Dao;

import com.zhao.bean.Goods;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

public class GoodsDao {
    private String driver="com.mysql.cj.jdbc.Driver";
    private static String url="jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC";
    private static String user="root";
    private static String password="root";
    private static Connection con=null;//数据库连接对象
    private PreparedStatement pstm=null;//预处理对象
    private ResultSet rs=null;//结果集对象
    private int row=0;//增删改受影响的行数


    public List<Goods> selectAll(){
        List<Goods> goodsList=new ArrayList<>();
        try {
            Class.forName(driver);
            con= DriverManager.getConnection(url,user,password);
            String sql="select * from t_goods";
            pstm=con.prepareStatement(sql);
            rs=pstm.executeQuery();
            while (rs.next()){
                //把当前数据行中的数据取出来,存储到Goods对象中
                Goods goods=new Goods();
                goods.setGid(rs.getInt("gid"));
                goods.setGname(rs.getString("gname"));
                goods.setPrice(rs.getString("price"));
                goods.setMark(rs.getString("mark"));

                //把Goods对象中存储到集合中
                goodsList.add(goods);
            }
        } catch (Exception e) {


        }finally {
            try {
                if (rs!=null){
                    rs.close();
                }
                if (pstm!=null){
                    pstm.close();
                }
                if (con!=null){
                     con.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return goodsList;
    }
}

SelectAllGoods.java页面(商品信息在页面展示)

package com.zhao.servlet;

import com.zhao.Dao.GoodsDao;
import com.zhao.bean.Goods;

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.util.List;

@WebServlet("/selectAllGoods")
public class SelectAllGoods extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置请求和响应的编码
        request.setCharacterEncoding("utf-8");//设置请求的编码
        response.setCharacterEncoding("utf-8");//设置响应的编码

        System.out.println("SelectAllGoods...doPost");

        //去查询数据库中商品信息表中的数据
        GoodsDao goodsDao=new GoodsDao();
        List<Goods> goodsList=goodsDao.selectAll();
        System.out.println(goodsList);

        //如何把商品信息传输到页面中进行展示---此处借助HttpSession传输数据
        HttpSession session=request.getSession();//获取HttpSession对象
        //把查询到商品信息集合存储到session对象中,起名字叫做goodsList
        session.setAttribute("goodsList",goodsList);
        response.sendRedirect("zhuye.jsp");
    }
}

最后跳转到主页上面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.List" %>
<%@ page import="com.zhao.bean.Goods" %><%--
  Created by IntelliJ IDEA.
  User: lenovo
  Date: 2023/2/17
  Time: 20:28
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--在页面导入jstl的核心类库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>主页</title>
</head>
<body>
<%--EL表达式是通过${} 从作用域对象中自动获取数据,如果是对象可以通过,访问其属性}--%>
<h2>欢迎来自${user.address}的${user.username}来到主页</h2>

<table>
    <tr>
        <th>商品编号</th>
        <th>商品名称</th>
        <th>商品价格</th>
        <th>商品说明</th>
    </tr>

<%--    items:要遍历的集合元素 var:临时变量--%>
    <c:forEach items="${goodsList}" var="goods">
        <tr>
            <td>${goods.gid}</td>
            <td>${goods.gname}</td>
            <td>${goods.price}</td>
            <td>${goods.mark}</td>
        </tr>
    </c:forEach>



</table>
</body>
</html>

运行后跳转到浏览器

页面展示效果

点击去登录

在数据库表中添加一条新的数据

在控制台上显示的数据


版权声明:本文为m0_73671382原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。