手写JavaSpring Boot
手写JavaSpring Boot
1.HTTP的交互流程:
HTTP的交互流程一般分为四个步骤(一次完整的请求):
一:
客户端和服务器端建立连接
二:
客户端发送请求数据到服务器端(HTTP协议)
三:
服务器端接受到请求后,进行处理,然后将处理结果响应客户端(HTTP协议)
四:
关闭客户端和服务器端的链接(HTTP1.1后不会立即关闭)
2.HTTP协议之请求格式
请求格式的结构:
请求头:请求方式、请求的地址和HTTP协议版本
请求行:消息报头,一般用来说明客户端要使用的一些附加信息。
空行:位于请求行和请求数据之间,空行是必须的。
3.HTTP协议之请求方式
根据HTTP标准,HTTP请求可以使用多种请求方法。HTTP1.0定义了三种请求方法:GET、POST和HEAD方法。HTTP1.1新增了五种请求方法:OPTIONS、PUT、DELETE、TRACE和CONNECT方法。
GET:请求指定的页面信息,并返回实体主体。
HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头。
POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件),数据被包含在请求体中。post请求可能会导致新的资源的建立和或已有资源的修改。
PUT:从客户端向服务器传送的数据取代指定的文档的内容。
DELETE:请求服务器删除指定的页面。
CONNECT:HTTP1.1协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS:允许客户端查看服务器的性能。
TRACE:回显服务器收到的请求主要用于测试或者判断
get和post请求方式的区别:
get请求方式:
请求数据会以?的形式隔开拼接在请求头中,不安全,没有请求实体部分。
HTTP协议虽然没有规定请求数据的大小,但是浏览器对URL的长度是有限制的,所以get请求不能携带大量的数据。
post请求方式:
请求数据在请求实体中进行发送,在URL中看不到具体的请求数据,安全。适合数据量大的数据发送。
所以模拟SpringBoot处理http的请求并回复响应
浏览器 ->发送请求(
例如 请求行: GET /index.html HTTP/1.1
消息头 HOST:localhost:8088
Connection:keep-alive
...
以及内容
)->ClientHandler 1.解析请求 2.处理请求 3.发送请求->回复给浏览器
1.解析请求 实例化HttpServleRequest
实例化httpServleResponse
HttpServletRequest 类
1.解析请求头 parseRequestLine
//解析请求行 private void parseRequestLine() throws IOException, EmptyRequestException { String line = readLine(); if(line.isEmpty()){//如果请求行没有读取到内容,则为空请求 throw new EmptyRequestException(); } System.out.println("请求行:" + line); String[] data = line.split("\\s"); method = data[0]; uri = data[1]; protocol = data[2]; parseURI(); } //进一步解析uri private void parseURI(){ String[] data = uri.split("\\?"); if(data.length==1){ requestURI = uri; }else{ requestURI = data[0]; queryString = data[1]; data = data[1].split("&"); for (int i = 0; i < data.length; i++) { String[] data1 = data[i].split("="); parameter.put(data1[0],data1.length>1?data1[1]:""); } } }
2.解析消息头
//解析消息头 private void parseHeaders() throws IOException { while (true) { String line = readLine(); if (line.isEmpty()) { break; } System.out.println("消息头:" + line); String[] data = line.split(":\\s"); headers.put(data[0].toLowerCase(), data[1]); } System.out.println("所有消息头:" + headers); } /** * 读取客户端发送过来的一行字符串 * * @return */ private String readLine() throws IOException {//被重用的代码对应的方法通常不自己处理异常 InputStream in = socket.getInputStream(); StringBuilder builder = new StringBuilder();//保存拼接的一行内容 char cur = 'a', pre = 'a';//cur记录本次读取的字符,pre记录上次读取的字符 int d;//每次读取的字节 while ((d = in.read()) != -1) { cur = (char) d;//将本次读取到的字节转换为char记录在cur上。 if (pre == 13 && cur == 10) {//如果上次读取的为回车符,本次读取的是换行符 break;//停止读取(一行结束了) } builder.append(cur);//将本次读取的字符拼接到已经读取的字符串中 pre = cur;//在下次读取前将本次读取的字符记作"上次读取的字符" } return builder.toString().trim(); }
3.解析消息正文
HttpServletResponse 响应对象
* 一个响应由三部分构成:
* 状态行,响应头,响应正文
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!