【仿写框架之仿写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;// 存储请求头中的KVprivate Map<String, String> headers = new HashMap<>();// url 中的参数和 body 中的参数都放到这个 parameters hash 表中.private Map<String, String> parameters = new HashMap<>();// 存储Cookieprivate 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.1String firstLine = bufferedReader.readLine();String[] firstLineTokens = firstLine.split(" ");request.method = firstLineTokens[0];request.url = firstLineTokens[1];request.version = firstLineTokens[2];// 2. 解析 urlint 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. 解析 cookieString cookie = request.headers.get("Cookie");if (cookie != null) {// 把 cookie 进行解析parseCookie(cookie, request.cookies);}// 5. 解析 bodyif ("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=123parseKV(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();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

配置使用Gitee账号认证登录Grafana

三方社会化身份源 集成gitee第三方登录 第三方登录的原理 所谓第三方登录&#xff0c;实质就是 OAuth 授权。用户想要登录 A 网站&#xff0c;A 网站让用户提供第三方网站的数据&#xff0c;证明自己的身份。获取第三方网站的身份数据&#xff0c;就需要 OAuth 授权。 举例来…

ubuntu上使用osg3.2+osgearth2.9

一、介绍 在ubuntu上使用osgearth加载三维数字地球&#xff0c;首先要有osg和osgearth的库&#xff0c;这些可以直接使用apt-get下载安装&#xff0c;但是版本有些老&#xff0c;如果需要新版本的就需要自己编译。 #查看现有版本 sudo apt-cache madison openscenegraph #安装…

Python写一个创意五子棋游戏

前言 在本教程中&#xff0c;我们将使用Python写一个创意五子棋游戏 &#x1f4dd;个人主页→数据挖掘博主ZTLJQ的主页 个人推荐python学习系列&#xff1a; ☄️爬虫JS逆向系列专栏 - 爬虫逆向教学 ☄️python系列专栏 - 从零开始学python 首先 GomokuGame 类的构造函数 __ini…

小程序 CSS-in-JS 和原子化的另一种选择

小程序 CSS-in-JS 和原子化的另一种选择 小程序 CSS-in-JS 和原子化的另一种选择 介绍快速开始 pandacss 安装和配置 0. 安装和初始化 pandacss1. 配置 postcss2. 检查你的 panda.config.ts3. 修改 package.json 脚本4. 全局 css 注册 pandacss5. 配置的优化与别名 weapp-pand…

LeetCode 周赛上分之旅 #40 结合特征压缩的数位 DP 问题

⭐️ 本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 和 BaguTree Pro 知识星球提问。 学习数据结构与算法的关键在于掌握问题背后的算法思维框架&#xff0c;你的思考越抽象&#xff0c;它能覆盖的问题域就越广&#xff0c;理解难度…

07_缓存预热缓存雪崩缓存击穿缓存穿透

缓存预热&缓存雪崩&缓存击穿&缓存穿透 一、缓存预热 提前将数据从数据库同步到redis。 在程序启动的时候&#xff0c;直接将数据刷新到redis懒加载&#xff0c;用户访问的时候&#xff0c;第一次查询数据库&#xff0c;然后将数据写入redis 二、缓存雪崩 发生情…

Roxy-Wi 命令执行漏洞复现

漏洞描述 Roxy-WI是开源的一款用于管理 Haproxy、Nginx 和 Keepalived 服务器的 Web 界面 Roxy-WI 6.1.1.0 之前的版本存在安全漏洞,该漏洞源于系统命令可以通过 subprocess_execute 函数远程运行,远程攻击者利用该漏洞可以执行远程代码。 免责声明 技术文章仅供参考,任…

小程序前台Boot后台校园卡资金管理系统java web学校进销存食堂挂失jsp源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 小程序前台Boot后台校园卡资金管理系统 系统有2权限&…

Nuxt3_1_路由+页面+组件+资源+样式 使用及实例

1、 简介 1.1 开发必备 node版本 v16.10.0 我使用的是16.14.0编辑器推荐使用Volar Extension 的VS code插件Terminal 运行nuxt指令 1.2 环境搭建 安装项目&#xff1a; npx nuxilatest init [first_nuxt3]进入项目目录&#xff1a; cd [first_nuxt3]安装依赖&#xff1a;n…

【蓝桥杯】[递归]母牛的故事

原题链接&#xff1a;https://www.dotcpp.com/oj/problem1004.html 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 我们列一个年份和母牛数量的表格&#xff1a; 通过观察&#xff0c;找规律&#xff0c;我们发现&#xff1a; 当年份小于等于4时&…

如何在出差期间远程访问企业ERP系统?内网穿透解决您的难题!

文章目录 概述1.查看象过河服务端端口2.内网穿透3. 异地公网连接4. 固定公网地址4.1 保留一个固定TCP地址4.2 配置固定TCP地址 5. 使用固定地址连接 概述 ERP系统对于企业来说重要性不言而喻&#xff0c;不管是财务、生产、销售还是采购&#xff0c;都需要用到ERP系统来协助。…

JVM前世今生之JVM内存模型

JVM内存模型所指的是JVM运行时区域&#xff0c;该区域分为两大块 线程共享区域 堆内存、方法区&#xff0c;即所有线程都能访问该区域&#xff0c;随着虚拟机和GC创建和销毁 线程独占区域 虚拟机栈、本地方法栈、程序计数器&#xff0c;即每个线程都有自己独立的区域&#…

华盛顿大学Baker实验室率先设计出双稳态结构蛋白质

在蛋白质世界&#xff0c;“结构决定功能”是一条基本原则。因此&#xff0c;很多人可能认为&#xff0c;一个蛋白质就应该有一个唯一确定的结构&#xff0c;使得它能够去执行确定的生物学功能。其实&#xff0c;在真实的世界中&#xff0c;蛋白质大多都是处于一种不断起伏的动…

依赖预构建与静态资源处理

依赖预构建 vite是一个基于浏览器原生ES-Module的前端构建工具。 当你首次启动vite的时候&#xff0c;vite会在本地加载你的站点之前预构建项目依赖。 原因&#xff1a; CommonJS和UMD兼容性&#xff1a;在开发阶段中&#xff0c;Vite的开发服务器将所有的代码视为原生ES模块。…

unity 之 GetComponent 获取游戏对象上组件实例方法

GetComponent 简单介绍 GetComponent 是Unity引擎中用于获取游戏对象上组件实例的方法。它允许您从游戏对象中获取特定类型的组件&#xff0c;以便在脚本中进行操作和交互。 GetComponent< ComponentType >(): 这是一个泛型方法&#xff0c;用于从当前游戏对象上获取指定…

【⑫MySQL | 约束(二)】外键 | 默认值 | 检查约束 — 综合案例

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL外键 | 默认值 | 检查约束 以及综合案例的分享✨ 目录 前言6. 外键约束(FOREIGN KEY,FK)7. 默认值约束和检查约束8. 综合实战总结 6. 外键约束(FOREIGN KEY,FK) 前面介绍的完整性约束都是在单表中进行设置&…

七夕前的爱心代码!

话不多说上代码&#xff01; import turtle as tu import random as ratu.setup(1.0, 1.0) tu.screensize(1.0, 1.0) tu.bgcolor(black) t tu.Pen() t.ht() colors [pink, hotpink, deeppink, lightpink, red, purple, violet, magenta]def draw_star(x, y, size, color):t.…

HASH索引,AVL树,B树,B+树的区别?

提前声明&#xff0c;本篇文章是我对我之前B树那篇文章的追加部分和补充的知识点&#xff0c;建议各位在看本篇文章的时候时已经了解了数据库索引B树的基本原理&#xff0c;否则有些地方可能理解起来会多一些难度哦&#xff01; 深入理解索引B树的基本原理_程序猿ZhangSir的博…

iOS17 widget Content margin

iOS17小组件有4个新的地方可以放置分别是&#xff1a;Mac桌面、iPad锁屏界面、 iPhone Standby模式、watch的smart stack Transition to content margins iOS17中苹果为widget新增了Content margin, 使widget的内容能够距离边缘有一定的间隙&#xff0c;确保内容显示完整。这…