IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> HTTP超文本传输协议基础学习 -> 正文阅读

[网络协议]HTTP超文本传输协议基础学习

HTTP超文本传输协议

概念:Hyper Text Tranfer Protocol 超文本传输协议

  • 传输协议:定义了,客户端和服务器端通信是,发送数据的格式
  • 特点:
    1. 基于TCP/IP的高级协议
    2. 默认端口号:80
    3. 基于请求/响应模型的:一次请求对应一次响应
    4. 无状态:每次请求之间相互独立,不能交互数据
  • 历史版本:
    1. 每一次请求响应都会建立新的连接
    2. 复用连接

请求消息数据格式

  1. 请求行

    • 请求方式 请求url 请求协议/版本

    • GET/login.html HTTP/1.1

    • 请求方式:

      • HTTP协议中有7种请求方式,常用的有两种
        • GET:
          1. 请求参数在请求行中,在url后
          2. 请求的url长度有限制的
          3. 不是很安全
        • POST:
          1. 请求参数在请求体中
          2. 请求的url长度没有限制
          3. 相对安全
  2. 请求头:客户端浏览器告诉服务器一些信息

    1. 请求头名称:请求头值
    2. 常见的请求头:
      1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息
        • 可以在服务器端获取该头的信息,解决浏览器的兼容性问题
      2. Referer: http://localhost:8080/MyApps/login.html
        • 告诉服务器,我(当前请求)从哪里来
          • 作用:
            1. 防盗链
            2. 统计
  3. 请求空行

    1. 空行:用于分割POST请求的请求头,和请求体的。
  4. 请求体(正文)

    • 封装POST请求消息的请求参数的
  5. 字符串格式:

    POST /MyApps/ser03 HTTP/1.1
    Host: localhost:8080
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 12
    Origin: http://localhost:8080
    Connection: keep-alive
    Referer: http://localhost:8080/MyApps/login.html
    Cookie: Idea-4311a65=5ac6d3b1-7c53-43e0-b438-60c6c2dbe879
    Upgrade-Insecure-Requests: 1
    Sec-Fetch-Dest: document
    Sec-Fetch-Mode: navigate
    Sec-Fetch-Site: same-origin
    Sec-Fetch-User: ?1
    
    USERNAME=ads
    

响应消息数据格式

Request

  1. request对象和response对象的原理

    1. request和response对象是由服务器创建的,我们来使用它们
    2. request对象来获取请求消息,response对象用来设置响应消息
  2. request对象继承体系结构

    • ServletRequest —接口
    • ? | 继承
    • HttpServletRequest —接口
    • ? | 实现
    • org.apache.catalina.connector.CoyoteInputStream 类(Tomcat)
  3. request:

    1. 获取请求消息数据

      1. 获取请求行数据

        • GET /MyApps/demo01?name=qin HTTP/1.1
        • 方法:
          1. 获取请求方式:GET
            • String getMethod()
          2. 获取虚拟目录:/MyApps
            • String getContextPath()
          3. 获取Servlet路径:/demo1
            • String getServletPath()
          4. 获取get方式的请求参数:name=qin
            • String getQueryString()
          5. 获取请求的uri:/MyApps/demo1
            • String getRequestURI():/MyApps/demo1
            • StringBuffer getRequestURL():http://localhost/MyApps/demo1
            • URL:统一资源定位符:http://localhost/MyApps/demo1
            • URI:统一资源标识符(范围更大):/MyApps/demo1
          6. 获取协议以及版本 HTTP/1.1
            • String getProtocol()
          7. 获取客户机的IP地址
            • String getRemoteAddr()
      2. 获取请求头数据

        • 方法:
          • String getHeader(String name):通过请求头的名称获取请求头的值
          • Enumeration<String> getHeaderNames():获取所有的请求头名称
      3. 获取请求体数据

        • 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数

        • 步骤:

          1. 获取流对象

            • BufferedReader getReader():获取字符输入流,只能操作字符数据

            • ServletInputStream getInputStream():获取字节输入流,可以操作所有类型的数据

            • regist.html

              <!DOCTYPE html>
              <html lang="en">
              <head>
                  <meta charset="UTF-8">
                  <title>注册</title>
              </head>
              <body>
                  <form action="rd5" method="post">
                      <input type="text" placeholder="请输入用户名" name="username">
                      <input type="text" placeholder="请输入密码" name="password"><br>
                      <input type="submit" value="submit">
                  </form>
              </body>
              </html>
              
            • RequestDemo5

              package com.web.request;
              
              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 java.io.BufferedReader;
              import java.io.IOException;
              
              @WebServlet("/rd5")
              public class RequestDemo05 extends HttpServlet {
                  @Override
                  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              
                  }
              
                  @Override
                  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                      //获取请求消息体--请求参数
              
                      //1.获取字符流
                      BufferedReader br = request.getReader();
                      //2.读取数据
                      String line = null;
                      while ((line = br.readLine())!=null){
                          System.out.println(line);
                      }
                  }
              }  
              
              
          2. 再从流对象中拿数据

    2. 其他功能

      1. 获取请求参数通用方式(无论GET或者POST):

        1. String getParameter(String name):根据参数名称获取参数值 username=qin&password=123

        2. String getParameterValues(String name):根据参数名称获取参数值的数组 hobby=xx&hobby=game

        3. Enumeration<String> getParameterNames():获取所有请求的参数名称

        4. Map<String,String[]> getParameterMap():获取所有参数的map集合

        5. 中文乱码问题

          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                  //post 获取请求参数
                  // 根据参数名称获取参数值
          	    //1. 设置请求request的编码
                  request.setCharacterEncoding("UTF-8");
                  String username = request.getParameter("username");
                  System.out.println(username);
                  try {
                      response.setCharacterEncoding("GBK");
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
                  response.getWriter().write(username);
              }
          }
          
          • get方式:Tomcat 8 已经将get方式乱码问题解决了

          • post方式:会乱码

            • 解决:在获取参数之前,设置request的编码

              //1. 设置请求request的编码
              request.setCharacterEncoding("UTF-8");
              
      2. 请求转发:一种在服务器内部的资源跳转方式

        1. 步骤:
          1. 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
          2. 使用RequestDispatcher对象来进行转发:RequestDispatcher.forward(ServletRequest request,ServletResponse response)
        2. 特点:
          1. 浏览器地址栏路径没有发生变化
          2. 只能访问转发到当前服务器内部资源中
          3. 有转发也是一次请求
      3. 共享数据:

        • 域对象:一个有作用范围的对象,可以在范围内共享数据
        • request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
        • 方法:
          1. setAttribute(String name,Object obj):存储数据
          2. getAttitude(String name):通过键获取值
          3. void removeAttribute(String name):通过键移除键值对
      4. 获取ServletContext:

        • ServletContext getServletContext()

小案例:用户登录

  • 用户登录案例需求:

    1. 编写login.html登录页面
      1. username&password 两个输入框
    2. 使用Druid数据库连接池技术,操作mysql,day14数据库中user表
    3. 使用jdbcTemplate技术封装JDBC
    4. 登录成功跳转到SuccessServlet展示:登录成功!
    5. 登录失败跳转到FailServlet展示:登录失败,用户名或密码错误
  • 分析

  • 开发步骤:

    1. 创建项目,导入html页面,配置文件,jar包

    2. 创建数据库环境

      create database	day14;
      use day14;
      create table User(
      	id int primary key auto_increment not null,
      	username varchar(32),
      	pwd varchar(32)
      )
      
    3. 创建包cn.domain,创建类User

      package cn.domain;
      
      
      /**
       * 用户的实体类
       */
      public class User {
          private String id;
          private String username;
          private String password;
      
      
          public String getId() {
              return id;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      
          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{" +
                      "id='" + id + '\'' +
                      ", username='" + username + '\'' +
                      ", password='" + password + '\'' +
                      '}';
          }
      }
      
      
    4. 创建包cn.op,创建UserOp,

      package cn.util;
      
      import com.alibaba.druid.pool.DruidDataSourceFactory;
      
      import javax.sql.DataSource;
      import java.io.IOException;
      import java.io.InputStream;
      import java.sql.Connection;
      import java.sql.SQLException;
      import java.util.Properties;
      
      /**
       * JDBC工具类 使用Durid连接池
       */
      public class JDBCUtils {
          private static DataSource ds;
      
          static {
              try {
              //1.加载配置文件
              Properties pro = new Properties();
              //使用ClassLoader加载配置文件,获取字节码输入流
              InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druif.properties");
              pro.load(is);//字节码输入
      
              //2.初始化连接池对象
                  ds = DruidDataSourceFactory.createDataSource(pro);
              } catch (IOException e) {
                  e.printStackTrace();
              } catch (Exception e) {
                  e.printStackTrace();
              }
      
      
          }
      
          /**
           * 获取连接池对象
           */
          public   static DataSource getDataSource(){
              return ds;
          }
      
          /**
           * 获取连接Connection对象
           */
          public static Connection getConnectyion() throws SQLException {
              return ds.getConnection();
      
          }
      
      }
      
      
    5. 创建包cn.op,创建类UserOp,提供login方法

      package cn.op;
      
      
      import cn.domain.User;
      import cn.util.JDBCUtils;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.dao.DataAccessException;
      import org.springframework.jdbc.core.BeanPropertyRowMapper;
      import org.springframework.jdbc.core.JdbcTemplate;
      
      /**
       * 操作数据库中User表的类
       */
      
      public class UserOp {
      
          //声明JDBCTemplate对象用来共用
          private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
          /**
           * 登录方法
           * @param loginUser 只有用户名和密码
           * @return  包含用户全部数据
           */
          public User login(User loginUser){
              try {
                  //1.编写sql
                  String sql = "select * from user where username = ? and pwd = ?;";
                  //2.调用query方法
                  User user = template.queryForObject(sql,
                          new BeanPropertyRowMapper<User>(User.class),
                          loginUser.getUsername(), loginUser.getPwd());
      
                  return user;
              } catch (DataAccessException e) {
                  e.printStackTrace();//记录日志
              }
              return null;
          }
          
      
      
      }
      
    6. 编写cn.web.servlet.LoginServlet类

      package cn.myweb.servlet;
      
      import cn.domain.User;
      import cn.op.UserOp;
      
      
      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 java.io.IOException;
      
      @WebServlet("/loginServlet")
      public class LoginServlet extends HttpServlet {
      
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              try {
                  //1.设置编码
                  req.setCharacterEncoding("utf-8");
                  //2.获取请求参数
                  String u = req.getParameter("username");
                  String p = req.getParameter("password");
                  //3.封装User对象
                  User logier = new User();
                  logier.setUsername(u);
                  logier.setPwd(p);
                  //调用UserOp的login方法
                  System.out.println(logier);
                  System.out.println("要进入");
                  UserOp op = new UserOp();
                  System.out.println("进入后");
                  User user = op.login(logier);
      
                  //5.判断user
                  if(user==null){
                      //登录失败
                      req.getRequestDispatcher("/failServlet").forward(req,resp);
                  }else{
                      //登录成功
                      //存储数据
                      req.setAttribute("user",user);
                      //转发/重定向
                      req.getRequestDispatcher("/successServlet").forward(req,resp);
                  }
              } catch (ServletException | IOException e) {
                  e.printStackTrace();
              }
      
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              this.doGet(req,resp);
          }
      }
      
      
    7. login.html中form表单的action路径的写法

      • 虚拟目录+Servlet的资源路径

      • <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>登录</title>
        </head>
        <body>
            <form action="/day14_2/loginServlet" method="post">
                <input type="text" name="username">
                <input type="password" name="pwd">
                <input type="submit" value="submit">
            </form>
        <!--    <a href="rd4">lianjie</a>-->
        </body>
        </html>
        
    8. BeanUtils工具类,完成数据封装

      • 用于封装JavaBean的

        1. JavaBean:标准的java类

          1. 要求:
            1. 类必须被public修饰
            2. 必须提供空参的构造器
            3. 成员变量必须使用private修饰
            4. 提供公用setter和getter方法
          2. 功能:封装数据
        2. 概念:

          • 成员变量:
          • 属性:setter和getter方法截取后的产物
            • 例如:getUsername() --> Username --> username
        3. 方法:

          1. setProperty()

          2. getProperty()

          3. populate(Object obj,Map map):将map集合的键值对信息,封装到对应的JavaBean对象中

            package cn.myweb.servlet;
            
            import cn.domain.User;
            import cn.op.UserOp;
            import com.mchange.v2.beans.BeansUtils;
            import com.mchange.v2.codegen.bean.BeangenUtils;
            import org.apache.commons.beanutils.BeanUtils;
            
            
            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 java.io.IOException;
            import java.lang.reflect.InvocationTargetException;
            import java.util.Map;
            
            @WebServlet("/loginServlet")
            public class LoginServlet extends HttpServlet {
            
                @Override
                protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                    try {
                        //1.设置编码
                        req.setCharacterEncoding("utf-8");
            //            //2.获取请求参数
            //            String u = req.getParameter("username");
            //            String p = req.getParameter("password");
            //            //3.封装User对象
            //            User logier = new User();
            //            logier.setUsername(u);
            //            logier.setPwd(p);
            
                        //2.获取所有请求参数
                        Map<String, String[]> map = req.getParameterMap();
                        //3.创建User对象
                        System.out.println("mima---"+map.get("password")[0]);;
                        User loginer = new User();
                        //3.2 使用BeanUtils封装
                        try {
                            BeanUtils.populate(loginer,map);//记住要用阿帕奇的不然会报错,把map里面的数据封装到User里面了
                        } catch (IllegalAccessException | InvocationTargetException e) {
                            e.printStackTrace();
                        }
                        //调用UserOp的login方法
                        System.out.println(loginer);
                        System.out.println("要进入");
                        UserOp op = new UserOp();
                        System.out.println("进入后");
                        User user = op.login(loginer);
            
                        //5.判断user
                        if(user==null){
                            //登录失败
                            req.getRequestDispatcher("/failServlet").forward(req,resp);
                        }else{
                            //登录成功
                            //存储数据
                            req.setAttribute("user",user);
                            //转发/重定向
                            req.getRequestDispatcher("/successServlet").forward(req,resp);
                        }
                    } catch (ServletException | IOException e) {
                        e.printStackTrace();
                    }
            
                }
            
                @Override
                protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                    this.doGet(req,resp);
                }
            }
            
            

(“user”,user);
//转发/重定向
req.getRequestDispatcher("/successServlet").forward(req,resp);
}
} catch (ServletException | IOException e) {
e.printStackTrace();
}

             }
         
             @Override
             protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                 this.doGet(req,resp);
             }
         }
         
         ```
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:52:13  更:2021-12-24 18:54:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/5 7:31:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码