实现简单的Http服务器+SpringMvc,集成到Spring

实现简单的Http服务器+SpringMvc,集成到Spring
1、Http协议
1.1、HTTP 协议请求格式
方法 + 空格 + URL + 空格 + 版本 + 回车符 + 换行符头部域名称:头部域值                 + 回车符 + 换行符...头部域名称:头部域值                 + 回车符 + 换行符回车符 + 换行符请求数据

利用Tcp接收一条Http请求数据如下:

GET /task/findAll?a=b HTTP/1.1
Host: localhost:8081
Connection: keep-alive
sec-ch-ua: "Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

完全符合上面的http协议的格式,反过来,可以根据上面的协议格式,解析Http的参数和需要的字段。

解析完后的实体如下:

{"headers": {"Accept": " text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","Connection": " keep-alive","User-Agent": " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36","Sec-Fetch-Site": " none","Sec-Fetch-Dest": " document","Host": " localhost","Accept-Encoding": " gzip, deflate, br","content-Type": "application/x-www-form-urlencoded","Sec-Fetch-Mode": " navigate","sec-ch-ua": " \"Google Chrome\";v=\"119\", \"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"","sec-ch-ua-mobile": " ?0","Cache-Control": " max-age=0","Upgrade-Insecure-Requests": " 1","sec-ch-ua-platform": " \"Windows\"","Sec-Fetch-User": " ?1","Accept-Language": " zh-CN,zh;q=0.9"},"methodName": "GET","protocol": "HTTP","queryString": {"a": "b"},"uri": "/task/findAll","version": "1.1"
}
1.2、http协议相应格式
版本 + 空格 + 状态码 + 空格 + 原因短句 + 回车符 + 换行符头部域名称:头部域值                             + 回车符 + 换行符...头部域名称:头部域值                             + 回车符 + 换行符回车符 + 换行符相应正文
1.3、请求及相应
public class Test {public static void main(String[] args) {HttpInvoke httpInvoke = new HttpInvoke() {@Overridepublic Object invoke(RequestEntity entity) {return "hello";}};BootstrapServer bootstrapServer = new BootstrapServer(8081, httpInvoke);}
}
// HttpInvoke作为请求的回调,这里只做简单的回应"hello",启动8081

在这里插入图片描述

传送门(在httptest包下)

2、SpringMvc
2.1、扫描组件包

扫描组件包,将每个接口请求封装成MethodHandler

Properties prop = PropertyUtils.getClassPathProperties(MVC_CLASSPATH_NAME);
packageScanner = new GenericPackagesScanner(ctx.getPackages());
// 1、找到被controller注解标记的类
Set<Class<?>> classes = packageScanner.getFullyQualifiedClassNameList();
Set<Class<?>> webSet = new HashSet<>();
Iterator<Class<?>> iterator = classes.iterator();
while (iterator.hasNext()) {Class<?> next = iterator.next();if(AnnotationUtils.containsAnyAnnotation(next, ControllerVax.class)) {webSet.add(next);}
}
// 2、解析处理方法
Iterator<Class<?>> controller = webSet.iterator();
List<MethodHandler> handlers = new ArrayList<>();
while (controller.hasNext()) {Class<?> next = controller.next();String commonUrl = AnnotationUtils.get(next, UrlMapping.class);List<Method> methods = ClassUtils.getMarkedMethod(next, UrlMapping.class);Iterator<Method> methodIt = methods.iterator();while (methodIt.hasNext()) {Method method = methodIt.next();String subUri = AnnotationUtils.get(method, UrlMapping.class);MethodHandler methodHandler = new MethodHandler();methodHandler.setMethod(method);methodHandler.setMethodURL(subUri);methodHandler.setClazz(next);methodHandler.setClazzUrl(commonUrl);methodHandler.setObj(ctx.getBean(next));methodHandler.setUrl(PathUtils.merge(commonUrl, subUri));methodHandler.setParameters(ClassUtils.getMethodParameters(method));if(handlers.contains(methodHandler)) {throw new MappingExistsException("method mapping exists");}handlers.add(methodHandler);}
}
2.2、匹配请求

遍历所有的MethodHandler,如果接口上的uri和请求中的uri一直,则将参数带进去执行,并将结果返回。

Iterator<MethodHandler> iterator = handlers.iterator();while (iterator.hasNext()) {// 接口方法MethodHandler handler = iterator.next();if(StringUtils.equals(handler.getUrl(), entity.getUri())) {// controller实例Object bean = ctx.getBean(handler.getClazz());Method method = handler.getMethod();List<String> parameters = handler.getParameters();List<Parameter> parameterType = Arrays.asList(method.getParameters());Object[] parameterVal = new Object[parameters.size()];for (int i = 0; i < parameters.size(); i++) {// 1、queryStringMap<String, String> queryString = entity.getQueryString();if(queryString != null && queryString.size() > 0) {parameterVal[i] = ObjectUtils.firstNotNull(queryString.get(parameters.get(i)));}// 2、body-json/form-dataMap<String, String> body = (Map<String, String>) entity.getBody();if(body != null && body.size() > 0) {parameterVal[i] = ObjectUtils.firstNotNull(body.get(parameters.get(i)));}if(!ObjectUtils.isSimpleType(parameterType.get(i).getType()) && StringUtils.equalsIgnore(entity.getContentType(), Constants.JSON_CONTENT_TYPE_VAL)) {parameterVal[i] = JSON.parseObject(entity.getBody().toString(), parameterType.get(i).getType());}}return ObjectUtils.invoke(bean, method, parameterVal);}}
3、Spring集成Mybatis

mybatis的代理对象,作为Spring组件,注入到容器中

JdbcManager jdbcManager = new JdbcManager(getJdbcProperties());
packageScanner.setPackages(ctx.getPackages());
this.classes = packageScanner.getFullyQualifiedClassNameList();
Iterator<Class<?>> iterator = this.classes.iterator();
// 2、移除没有被注解标记的类
while (iterator.hasNext()) {Class<?> clazz = iterator.next();if(!AnnotationUtils.containsAnyAnnotation(clazz, GlobalConstants.MAPPER_ANNOTATIONS)) {iterator.remove();continue;}ctx.registry(clazz.getSimpleName(), ProxyUtils.getProxy(clazz, new MapperProxyFactory(jdbcManager)));
}
ctx.refresh(false);
4、运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
传送门

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

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

相关文章

VMware下载安装教程

目录 一.下载二.安装 一.下载 官网地址&#xff1a;官网 下载的时候选择Workstation Player&#xff0c;这个是免费的&#xff0c;当然你也可以选择下载Workstation Pro。 二.安装 下载完成之后点击安装包按照需要安装即可。 安装之后启动&#xff0c;可以看到这个能够免费使…

26. 深度学习进阶 - 深度学习的优化方法

Hi, 你好。我是茶桁。 上一节课中我们预告了&#xff0c;本节课是一个难点&#xff0c;同时也是一个重点&#xff0c;大家要理解清楚。 我们在做机器学习的时候&#xff0c;会用不同的优化方法。 SGD 上图中左边就是Batch Gradient Descent&#xff0c;中间是Mini-Batch Gra…

Linux系统的常见命令十三,显示系统进程状态、文件权限、修改文件或目录所有者和所属组命令(ps、chmod和chown)

本文主要介绍Linux系统的显示系统进程状态、文件权限、修改文件或目录所有者和所属组命令&#xff0c;&#xff08;ps、chmod和chown&#xff09; 目录 显示系统进程状态文件权限设置&#xff08;chmod&#xff09;修改文件或目录所有者和所属组&#xff08;chown&#xff09; …

进制转化总结

来源&#xff0c;做个笔记&#xff0c;讲的还蛮清楚通信原理-2.5 数据封装与传输05_哔哩哔哩_bilibili ip地址范围 ​​​​​​​

39.从0到上线三天搭建个人网站(第三天)

点赞收藏加关注&#xff0c;你也能住大别墅&#xff01; 一、第三天主要工作 1.完成detail页面的开发 2.将所有数据以及部分静态资源存在uniCloud&#xff0c;为以后做管理后台做准备 3.创建云对象getData&#xff0c;在beforecreate&#xff08;&#xff09;中获取数据 4.…

C++ list容器

文章目录 C++ list容器list基本概念list构造函数list 赋值和交换list 大小操作list 插入和删除list 数据存取list 反转和排序排序案例C++ list容器 list基本概念 功能:将数据进行链式存储 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中…

8通道16位数据采集卡方案

硬件方案--采集板 下载链接&#xff01;https://mp.weixin.qq.com/s?__bizMzU2OTc4ODA4OA&mid2247558420&idx1&sn3b1d6a99a69e68c32f425e489c21b6d5&chksmfcfaf6c3cb8d7fd52961827dedf30a79e65ed96e5b507bc5027d80f9285aa9bdcf790b940b51&token1650944467…

python之pyqt专栏10-键盘事件

需求 通过按键盘的上下左右&#xff0c;移动button的位置。 UI界面设计 代码 # 导入sys模块 import sysfrom PyQt6.QtCore import Qt # PyQt6.QtWidgets模块中导入QApplication, QWidget from PyQt6.QtWidgets import QApplication, QWidget# untitled模块中导入Ui_Form类 f…

跳表的基础

跳表的作用 无需数组查找目标元素-----从头遍历---O(n); 有序数组查找目标元素-----二分查找---O(logn); 链表查找目标元素----------只能从头遍历---O(n); 那么链表要如何实现O(logn)的查找时间复杂度呢-----跳表。 跳表的定义 有序链表多级索引跳表 就是一个多级链表 …

css小技巧 linear-gradient

设计图&#xff1a; 现在的要求是不准用图片&#xff0c;好吧&#xff0c;那就用代码简单实现下。 方式1&#xff1a;svg <svg xmlns"http://www.w3.org/2000/svg" version"1.1"><rect x"-30" y"1" rx"8" ry&quo…

栈实现队列,力扣

题目地址&#xff1a; 232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; 难度&#xff1a;简单 今天刷栈实现队列&#xff0c;大家有兴趣可以点上看看题目要求&#xff0c;试着做一下。 题目&#xff1a; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支…

xilinx系列FPGA基于VIVADO的pin delay列表生成说明

目录 1 概述2 示例平台3 操作说明4 注意事项 xilinx系列FPGA基于VIVADO的pin delay列表生成说明 1 概述 本文用于讲诉xilinx系列FPGA基于VIVADO的pin delay列表生成说明&#xff0c;以及一些注意事项&#xff0c;为FPGA设计人员探明道路。 Pin delay 即FPGA内部die到pin的延时…