【仿写框架之仿写Tomact】四、封装HttpRequest对象(属性映射http请求报文)、HttpResponse对象(属性映射http响应报文)

文章目录

  • 1、创建HttpRequest对象
  • 2、创建HttpResponse对象

在这里插入图片描述

1、创建HttpRequest对象

HttpRequest对象中的属性与HTTP协议中的内容对应,用于后序servlet从request中获取请求中的参数。

参照http请求报文:
在这里插入图片描述
在这里插入图片描述

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class HttpRequest {
    private String method;
    private String url;
    private String version;
    // 存储请求头中的KV
    private Map<String, String> headers = new HashMap<>();
    // url 中的参数和 body 中的参数都放到这个 parameters hash 表中.
    private Map<String, String> parameters = new HashMap<>();
    // 存储Cookie
    private Map<String, String> cookies = new HashMap<>();
    private String body;

    public static HttpRequest build(InputStream inputStream) throws IOException {
        HttpRequest request = new HttpRequest();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        // 1. 处理首行 GET /url /HTTP/1.1
        String firstLine = bufferedReader.readLine();
        String[] firstLineTokens = firstLine.split(" ");
        request.method = firstLineTokens[0];
        request.url = firstLineTokens[1];
        request.version = firstLineTokens[2];
        // 2. 解析 url
        int pos = request.url.indexOf("?");
        //2.1 如果有?号,也间接说明这是一个GET请求
        if (pos != -1) {
            // 2.1.1截取出所有参数
            String queryString = request.url.substring(pos + 1);
            // 2.2.2将参数解析为KV后存储
            parseKV(queryString, request.parameters);
        }
        // 3. 循环处理 header 部分
        String line = "";
        while ((line = bufferedReader.readLine()) != null && line.length() != 0) {
            String[] headerTokens = line.split(": ");
            request.headers.put(headerTokens[0], headerTokens[1]);
        }
        // 4. 解析 cookie
        String cookie = request.headers.get("Cookie");
        if (cookie != null) {
            // 把 cookie 进行解析
            parseCookie(cookie, request.cookies);
        }
        // 5. 解析 body
        if ("POST".equalsIgnoreCase(request.method)
                || "PUT".equalsIgnoreCase(request.method)) {
            // 这两个方法需要处理 body, 其他方法暂时不考虑
            // 需要把 body 读取出来.
            // 需要先知道 body 的长度. Content-Length 就是干这个的.
            // 此处的长度单位是 "字节"
            int contentLength = Integer.parseInt(request.headers.get("Content-Length"));
            // 注意体会此处的含义~~
            // 例如 contentLength 为 100 , body 中有 100 个字节.
            // 下面创建的缓冲区长度是 100 个 char (相当于是 200 个字节)
            // 缓冲区不怕长. 就怕不够用. 这样创建的缓冲区才能保证长度管够~~
            char[] buffer = new char[contentLength];
            // 把
            int len = bufferedReader.read(buffer);
            request.body = new String(buffer, 0, len);
            // body 中的格式形如: username=tanglaoshi&password=123
            parseKV(request.body, request.parameters);
        }
        return request;
    }

    private static void parseCookie(String cookie, Map<String, String> cookies) {
        // 1. 按照 分号空格 拆分成多个键值对
        String[] kvTokens = cookie.split("; ");
        // 2. 按照 = 拆分每个键和值
        for (String kv : kvTokens) {
            String[] result = kv.split("=");
            cookies.put(result[0], result[1]);
        }
    }

    private static void parseKV(String queryString, Map<String, String> parameters) {
        // 1. 按照 & 拆分成多个键值对
        String[] kvTokens = queryString.split("&");
        // 2. 按照 = 拆分每个键和值
        for (String kv : kvTokens) {
            String[] result = kv.split("=");
            parameters.put(result[0], result[1]);
        }
    }

    public String getMethod() {
        return method;
    }

    public String getUrl() {
        return url;
    }

    public String getVersion() {
        return version;
    }

    public String getBody() {
        return body;
    }

    public String getParameter(String key) {
        return parameters.get(key);
    }

    public String getHeader(String key) {
        return headers.get(key);
    }

    public String getCookie(String key) {
        return cookies.get(key);
    }
}


2、创建HttpResponse对象

参照http请求报文:
在这里插入图片描述
在这里插入图片描述

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

public class HttpResponse {
    private String version = "HTTP/1.1";
    private int status;
    private String message;
    private Map<String, String> headers = new HashMap<>();
    private StringBuilder body = new StringBuilder();
    private OutputStream outputStream = null;

    public static HttpResponse build(OutputStream outputStream) {
        HttpResponse response = new HttpResponse();
        response.outputStream = outputStream;
        return response;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void setHeader(String key, String value) {
        headers.put(key, value);
    }

    public void writeBody(String content) {
        body.append(content);
    }

    public void flush() throws IOException {
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write(version + " " + status + " " + message + "\n");
        headers.put("Content-Length", body.toString().getBytes().length + "");
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            bufferedWriter.write(entry.getKey() + ": " + entry.getValue() + "\n");
        }
        bufferedWriter.write("\n");
        bufferedWriter.write(body.toString());
        bufferedWriter.flush();
    }
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/77614.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年国赛数学建模思路 - 案例:最短时间生产计划安排

文章目录 0 赛题思路1 模型描述2 实例2.1 问题描述2.2 数学模型2.2.1 模型流程2.2.2 符号约定2.2.3 求解模型 2.3 相关代码2.4 模型求解结果 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 最短时…

FreeModbus——介绍(二)

1.简介 freemodbus_百度百科 (baidu.com) &#xff1a;参考自百度百科&#xff0c;里面还有移植介绍&#xff0c;非常详细 1. FreeMODBUS是一个奥地利人写的Modbus协议。它是一个针对嵌入式应用的一个免费&#xff08;自由&#xff09;的通用MODBUS协议的移植。 2. FreeMOD…

【Linux】模拟实现linux的shell

#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/wait.h> #include <sys/types.h> #define NUM 1024 #define SIZE 32 #define SEP " " int main() {//保存输入后的字符串char …

夏威夷等全球多地深陷「末日狂烧」,关键时刻 AI 监测能否跑赢野火?

内容一览&#xff1a;当地时间 8 月 8 日&#xff0c;美国夏威夷州突发野火&#xff0c;当地居民和游客不得不跳入太平洋中躲避火势。截至 8 月 17 日&#xff0c;这场野火已经造成110 人死亡&#xff0c;超过 1000人失踪。与此同时&#xff0c;美国、加拿大、法国等地也正遭遇…

消息队列总结

前言 你用过消息队列么&#xff1f; 说说你们项目里是怎么用消息队列的&#xff1f; 我们有一个订单系统&#xff0c;订单系统会每次下一个新订单的时候&#xff0c;就会发送一条消息到ActiveMQ里面去&#xff0c;后台有一个库存系统&#xff0c;负责获取消息&#xff0c;然后…

实时会话简易版

1、数据存储 Redis缓存、pgsql数据库 2、存储使用 2.1、Redis缓存 1&#xff09;无序集合set&#xff1a;存储未读会话id 2&#xff09;list&#xff08;左进右出&#xff09;&#xff1a;存储会话未读消息 2.2、pgsql数据库 存储用户信息&#xff0c;存储会话id&#…

09 - 连续的多个commit整理成1个

查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;GIT常用场景- 目录 文章目录 将连续的多个commit整理成1个 将连续的多个commit整理成1个 将anranxiaohunzhang和xianglongshibazhang合并起来&#xff08;将anranxiaohunzhang合并到降龙十八掌上&#xff0c;生成新…

【校招VIP】java语言考点之ConcurrentHashMap1.7和1.8

考点介绍&#xff1a; ConcurrentHashMap是JAVA校招面试的热门考点&#xff0c;主要集中在1.7和1.8的底层结构和相关的性能提高。 理解这个考点要从map本身的并发问题出发&#xff0c;再到hashTable的低性能并发安全&#xff0c;引申到ConcurrentHashMap的分块处理。同时要理解…

R语言实现计算净重新分类指数(NRI)和综合判别改善指数(IDI)

两个模型比较&#xff0c;与第一个模型相比&#xff0c;NRI&#xff08;重新分对的 - 重新分错的&#xff09;/总人数。IDI&#xff08;新模型患者平均预测概率-旧模型患者平均预测概率&#xff09;-&#xff08;新模型非患者平均预测概率-旧模型非患者平均预测概率&#xff09…

nginx代理请求到内网不同服务器

需求&#xff1a;之前用的是frp做的内网穿透&#xff0c;但是每次电脑断电重启&#xff0c;路由或者端口会冲突&#xff0c;现在使用汉土云盒替换frp。 需要把公网ip映射到任意一台内网服务器上&#xff0c;然后在这台内网服务器上用Nginx做代理即可访问内网其它服务器&#xf…

如何使用CSS实现一个渐变背景效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现渐变背景效果⭐ 线性渐变&#xff08;Linear Gradient&#xff09;⭐ 径向渐变&#xff08;Radial Gradient&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订…

微服务实战项目-学成在线-项目优化(redis缓存优化)

微服务实战项目-学成在线-项目优化(redis缓存优化) 1 优化需求 视频播放页面用户未登录也可以访问&#xff0c;当用户观看试学课程时需要请求服务端查询数据&#xff0c;接口如下&#xff1a; 1、根据课程id查询课程信息。 2、根据文件id查询视频信息。 这些接口在用户未认…

W6100-EVB-PICO 做UDP Server进行数据回环测试(七)

前言 前面我们用W6100-EVB-PICO 开发板在TCP Client和TCP Server模式下&#xff0c;分别进行数据回环测试&#xff0c;本章我们将用开发板在UDP Server模式下进行数据回环测试。 UDP是什么&#xff1f;什么是UDP Server&#xff1f;能干什么&#xff1f; UDP (User Dataqram P…

带你了解—使用内网穿透,公网远程访问本地硬盘文件

文章目录 前言1. 下载cpolar和Everything软件3. 设定http服务器端口4. 进入cpolar的设置5. 生成公网连到本地内网穿透数据隧道 总结 前言 随着云概念的流行&#xff0c;不少企业采用云存储技术来保存办公文件&#xff0c;同时&#xff0c;很多个人用户也感受到云存储带来的便利…

打造专属照片分享平台:快速上手Piwigo网页搭建

文章目录 通过cpolar分享本地电脑上有趣的照片&#xff1a;部署piwigo网页前言1.Piwigo2. 使用phpstudy网页运行3. 创建网站4. 开始安装Piwogo 总结 &#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x…

我国农机自动驾驶系统需求日益增长,北斗系统赋能精准农业

中国现代农业的发展&#xff0c;离不开智能化、自动化设备&#xff0c;迫切需要自动驾驶系统与农用机械的密切结合。自动驾驶农机不仅能够缓解劳动力短缺问题&#xff0c;提升劳作生产效率&#xff0c;同时还能对农业进行智慧化升级&#xff0c;成为解决当下农业痛点的有效手段…

『论文精读』Data-efficient image Transformers(DeiT)论文解读

『论文精读』Data-efficient image Transformers(DeiT)论文解读 文章目录 一. DeiT简介二. 知识蒸馏(knowledge distillation)2.1. KLDivloss2.2. 蒸馏温度 τ \tau τ2.3. distillation in transformer 三. better hyperparameter四. data augmentation五. label smoothing参…

C语言快速回顾(三)

前言 在Android音视频开发中&#xff0c;网上知识点过于零碎&#xff0c;自学起来难度非常大&#xff0c;不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》&#xff0c;结合我自己的工作学习经历&#xff0c;我准备写一个音视频系列blog。C/C是音视频必…

一分钟上手Vue VueI18n Internationalization(i18n)多国语言系统开发、国际化、中英文语言切换!

这里以Vue2为例子 第一步&#xff1a;安装vue-i18n npm install vue-i18n8.26.5 第二步&#xff1a;在src下创建js文件夹&#xff0c;继续创建language文件夹 在language文件夹里面创建zh.js、en.js、index.js这仨文件 这仨文件代码分别如下&#xff1a; zh.js export de…

踩坑串口通信 serialPort.RtsEnable = true

背景&#xff1a; 最近在调试一个激光模块&#xff0c;使用的是422通信&#xff0c;然后买了一个485转422的转换器。 通过串口监控软件观察&#xff0c;明明和串口助手发的东西一模一样&#xff0c;但是就是不返回&#xff01; 解决方案&#xff1a; 我加了&#xff0c;这句&…