JavaWeb-19-HTTP协议-概述-请求-响应-解析

一、HTTP协议-概述

  • 在浏览器输入地址后,浏览器默认会自动在请求路径前面加上一个协议:HTTP

    image-20230826201931820

  • 概念Hyper Text Transfer Protocol(超文本传输协议),规定了浏览器和服务器之间数据传输的规则。

    image-20230826201830410

  • HTTP:是数据传输的规则、格式:

    • 分别是请求和响应数据的格式。
  • 特点:

    1. 基于TCP协议:面向连接,安全

    2. 基于请求-响应模型的:一次请求对应一次响应

    3. HTTP协议是无状态的协议:对于事务处理没有记忆能力。

      • 无状态:每一次请求、响应都是独立的;后一次请求是不会记录前一次请求数据的。

      • 缺点:多次请求间不能共享数据。

      • 优点:速度快



二、HTTP协议-请求协议

image-20230826202011875

1. 数据含义

image-20230826202027651

Host请求的主机名
User-Agent浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 … Chrome/79,
IE浏览器的标识类似Mozilla/5.0 (Windows NT …) like Gecko
Accept表示浏览器能接收的资源类型,如text/*,image/或者/*表示所有;
Accept-Language表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;
Accept-Encoding表示浏览器可以支持的压缩类型,例如gzip, deflate等。
Content-Type请求主体的数据类型。
Content-Length请求主体的大小(单位:字节)。
2. GET和POST的区别

image-20230826202100469


image-20230826202543690

  • 01.GET-POST.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>请求方式演示-GET-POST</title>
    </head>
    <body>
        <form action="" method="get">
            姓  名: <input type="text" name="name"> <br>
            密  码: <input type="password" name="password"> <br>
            <input type="submit" value="提交(GET)">
        </form>
    
        <br><br>
    
        <form action="" method="post">
            姓  名: <input type="text" name="name"> <br>
            密  码: <input type="password" name="password"> <br>
            <input type="submit" value="提交(POST)">
        </form>
    </body>
    </html>
    

    image-20230826202945675

(1)请求方式-GET
  • 请求参数在请求行中,没有请求体,如:/brand/findAll?name=OPPO&status=1。GET请求大小是有限制的。

    image-20230826203131238

image-20230826203342875


(2)请求方式-POST
  • 请求参数在请求体中,POST请求大小是没有限制的。

image-20230826203748179

image-20230826203832071

image-20230826204011942



三、HTTP协议-响应协议

image-20230826204031798

1. 数据含义

image-20230826204055023


2. 状态码
状态码分类说明
1xx响应中——临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它
2xx成功——表示请求已经被成功接收,处理已完成
3xx重定向——重定向到其它地方:它让客户端再发起一个请求以完成整个处理。
4xx客户端错误——处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等
5xx服务器端错误——处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

3.常见响应头
响应头说明
Content-Type表示该响应内容的类型,例如text/html,application/json。
Content-Length表示该响应内容的长度(字节数)。
Content-Encoding表示该响应压缩算法,例如gzip。
Cache-Control指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒。
Set-Cookie告诉浏览器为当前页面所在的域设置cookie。

4.常见的响应状态码
状态码英文描述解释
200OK客户端请求成功,即处理成功,这是我们最想看到的状态码
302Found指示所请求的资源已移动到由Location响应头给定的 URL,浏览器会自动重新访问到这个页面
304Not Modified告诉客户端,你请求的资源至上次取得后,服务端并未更改,你直接用你本地缓存吧。隐式重定向
400Bad Request客户端请求有语法错误,不能被服务器所理解
403Forbidden服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源
404Not Found请求资源不存在,一般是URL输入有误,或者网站资源被删除了
405Method Not Allowed请求方式有误,比如应该用GET请求方式的资源,用了POST
428Precondition Required服务器要求有条件的请求,告诉客户端要想访问该资源,必须携带特定的请求头
429Too Many Requests指示用户在给定时间内发送了太多请求(“限速”),配合 Retry-After(多长时间后可以请求)响应头一起使用
431 Request Header Fields Too Large请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少请求头域的大小后重新提交。
500Internal Server Error服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧
503Service Unavailable服务器尚未准备好处理请求,服务器刚刚启动,还未初始化好

状态码大全:https://cloud.tencent.com/developer/chapter/13553

  • 目前阶段只需要知道:
  • 200、404、500


四、HTTP协议-协议解析

image-20230826204959741

1. 客户端
  • 客户端浏览器各大厂商给我们提供了,里面已经内置了解析HTTP协议的程序
  • 因此当服务端给客户端浏览器响应对应的数据后,客户端浏览器会自动解析

2. 服务端
  • 在服务器端通过Java程序接收客户端浏览器发起的请求并获取请求数据
  • 然后参照前面介绍的HTTP协议请求数据格式对请求数据进行解析
  • 最后参照前面介绍的HTTP协议响应数据格式给客户端浏览器响应对应的数据

  • 服务端程序实现HTTP协议解析程序:

(1)我们可以Socket、ServerSocket可以写出一个服务器端的程序

(2)然后浏览器发送HTTP请求,我们通过ServerSocket来接收客户端发起的请求并获取到请求数据

(3)这些请求数据就是一些字符串,格式就是之前介绍过的,根据字符串的组成规则解析它

(4)通过ServerSocket来获取到输出流,按照HTTP响应数据格式给浏览器响应一个固定格式的字符串

image-20230826205148646

  • Server.java

    package com.itheima;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    
    /*
     * 自定义web服务器
     */
    public class Server {
        public static void main(String[] args) throws IOException {
            ServerSocket ss = new ServerSocket(8081); // 监听指定端口
            System.out.println("server is running...");
    
            while (true){
                Socket sock = ss.accept();
                System.out.println("connected from " + sock.getRemoteSocketAddress());
    
                //开启线程处理请求
                Thread t = new Handler(sock);
                t.start();
            }
        }
    }
    
    class Handler extends Thread {
        Socket sock;
    
        public Handler(Socket sock) {
            this.sock = sock;
        }
    
        public void run() {
            try (InputStream input = this.sock.getInputStream(); OutputStream output = this.sock.getOutputStream()) {
                    handle(input, output);
            } catch (Exception e) {
                try {
                    this.sock.close();
                } catch (IOException ioe) {
                }
                System.out.println("client disconnected.");
            }
        }
    
        private void handle(InputStream input, OutputStream output) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
    
            // 读取HTTP请求:
            boolean requestOk = false;
            String first = reader.readLine();
            if (first.startsWith("GET / HTTP/1.")) {
                requestOk = true;
            }
    
            for (;;) {
                String header = reader.readLine();
                if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
                    break;
                }
                System.out.println(header);
            }
            System.out.println(requestOk ? "Response OK" : "Response Error");
    
            if (!requestOk) {// 发送错误响应:
                writer.write("HTTP/1.0 404 Not Found\r\n");
                writer.write("Content-Length: 0\r\n");
                writer.write("\r\n");
                writer.flush();
            } else {  // 发送成功响应:
                //读取html文件,转换为字符串
                InputStream is = Server.class.getClassLoader().getResourceAsStream("html/a.html");
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                StringBuilder data = new StringBuilder();
                String line = null;
                while ((line = br.readLine()) != null){
                    data.append(line);
                }
                br.close();
                int length = data.toString().getBytes(StandardCharsets.UTF_8).length;
    
                writer.write("HTTP/1.1 200 OK\r\n");
                writer.write("Connection: keep-alive\r\n");
                writer.write("Content-Type: text/html\r\n");
                writer.write("Content-Length: " + length + "\r\n");
                writer.write("\r\n"); // 空行标识Header和Body的分隔
                writer.write(data.toString());
                writer.flush();
            }
        }
    }
    
  • a.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <table border="1" cellspacing="0" width="500">
        <tr>
            <th>序号</th>
            <th>品牌名称</th>
            <th>企业名称</th>
    
        </tr>
        <tr align="center">
            <td>010</td>
            <td>三只松鼠</td>
            <td>三只松鼠</td>
        </tr>
    
        <tr align="center">
            <td>009</td>
            <td>优衣库</td>
            <td>优衣库</td>
        </tr>
    
        <tr align="center">
            <td>008</td>
            <td>小米</td>
            <td>小米科技有限公司</td>
        </tr>
    
    
    </table>
    
    
    </body>
    </html>
    

    image-20230826205721094

    image-20230826205903396

    image-20230826205845878


3. 软件解析
  • 如果我们真的要写一个程序来解析HTTP协议,是要考虑到各种情况的,里面东西很多。

  • 代码量也是相当大,繁琐。

  • 但是所有web开发都是要解析HTTP协议的,因此是通用的。

  • 所以有很多公司已经把这些代码写好了,并封装到一个软件程序中提供给我们使用,这个软件就是Web服务器

  • Web服务器有很多:

    image-20230826205926208

  • 有了这些Web服务器,HTTP解析和处理的代码都不用我们去做了!!这样更加便捷、高效。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java EE 项目的目录结构可以根据具体的需求进行灵活设计,但一般情况下,推荐使用以下的标准目录结构: ``` project ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ └── example │ │ │ ├── controller │ │ │ ├── dao │ │ │ ├── entity │ │ │ ├── service │ │ │ └── util │ │ ├── resources │ │ │ ├── mapper │ │ │ └── db.properties │ │ └── webapp │ │ ├── WEB-INF │ │ │ ├── classes │ │ │ ├── lib │ │ │ └── web.xml │ │ ├── css │ │ ├── js │ │ ├── images │ │ └── index.jsp │ └── test │ ├── java │ └── resources ├── target ├── pom.xml └── README.md ``` 其中,各个目录的作用如下: - `src/main/java`:存放项目的 Java 源代码,按照包名分层,一般包括 `controller`、`dao`、`entity`、`service` 和 `util` 等包; - `src/main/resources`:存放项目的配置文件和资源文件,一般包括数据库连接配置文件 `db.properties`、MyBatis 的 mapper 文件等; - `src/main/webapp`:存放 Web 应用的 Web 资源,包括 JSP 页面、CSS 样式表、JavaScript 脚本等; - `src/test/java`:存放项目的测试代码; - `src/test/resources`:存放测试代码所需要的资源文件; - `target`:存放编译后的 .class 文件、打包后的 .war 文件等; - `pom.xml`:Maven 项目管理工具的配置文件; - `README.md`:项目说明文件。 以上是一种常见的 Java EE 项目目录结构,但并不是唯一的标准。在实际开发中,可以根据项目的具体需求进行合理的调整和修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值