上节课我们自己动手制作了一个RPC框架,本节课我们挑战一个稍有难度的一点的任务,手动制作一个Web框架。

首先我们看看这个Web框架使用起来如何简单

Hello World

import httpkids.server.KidsRequestDispatcher;
import httpkids.server.Router;
import httpkids.server.internal.HttpServer;public class HelloWorld {public static void main(String[] args) {var rd = new KidsRequestDispatcher("/kids", new Router((ctx, req) -> {ctx.html("Hello, World");}));new HttpServer("localhost", 8080, 2, 16, rd).start();}}http://localhost:8080/kids

KidsRequestDispatcher是请求派发器,用于将收到的HTTP请求对象扔给响应的RequestHandler进行处理。Router用于构建路由,它负责的是将URL规则和RequestHandler挂接起来,形成一个复杂的映射表。

Router为了简化实现细节,所以没有支持复杂的URL规则,例如像RESTFUL这种将参数写在URL里面的这种形式是不支持的。

HttpServer是Web服务器的核心对象,构建HttpServer除了IP端口之外,还需要提供3个关键参数,分别是IO线程数、业务线程数和请求派发器对象。IO线程用于处理套件字读写,由Netty内部管理。业务线程专门用于处理HTTP请求,由httpkids框架来管理。

一个全面的例子

import java.util.HashMap;import httpkids.server.KidsRequestDispatcher;
import httpkids.server.Router;
import httpkids.server.internal.HttpServer;public class HelloWorld {public static void main(String[] args) {var router = new Router((ctx, req) -> {ctx.html("Hello, World"); // 纯文本网页}).handler("/hello.json", (ctx, req) -> {ctx.json(new String[] { "Hello", "World" });  // json api}).handler("/hello", (ctx, req) -> {var res = new HashMap<String, Object>();res.put("req", req);ctx.render("playground.ftl", res);  // 模版渲染}).handler("/world", (ctx, re) -> {ctx.redirect("/hello");  // 302跳转}).child("/user", () -> {  //  URL嵌套return new Router((ctx, req) -> {ctx.html("Hello, World");}).handler("/hello.json", (ctx, req) -> {ctx.json(new String[] { "Hello", "World" });}).handler("/hello", (ctx, req) -> {var res = new HashMap<String, Object>();res.put("req", req);ctx.render("playground.ftl", res);}).handler("/world", (ctx, re) -> {ctx.redirect("/hello");}).filter((ctx, req, before) -> {  // 请求过滤器、拦截器if (before) {System.out.printf("before %s\n", req.path());} else {System.out.printf("after %s\n", req.path());}return true;});}).resource("/pub", "/static");var rd = new KidsRequestDispatcher("/kids", router);rd.templateRoot("/tpl"); // 模版所在的classpath目录var server = new HttpServer("localhost", 8080, 2, 16, rd);server.start();// 优雅停机Runtime.getRuntime().addShutdownHook(new Thread() {public void run() {server.stop();}});}}http://localhost:8080/kids
http://localhost:8080/kids/hello
http://localhost:8080/kids/hello.json
http://localhost:8080/kids/world
http://localhost:8080/kids/user
http://localhost:8080/kids/user/hello
http://localhost:8080/kids/user/hello.json
http://localhost:8080/kids/user/world
http://localhost:8080/kids/pub/bootstrap.min.css

堆栈深度

非Java程序员总是抱怨Java的框架过于复杂,特别爱拿Java恐怖的调用栈说事。比如下面这张图广为流传。

所以这里我要亮出httpkids的调用栈,我们来看看它到底有多深

项目代码

https://github.com/pyloque/httpkids

https://github.com/pyloque/rpckids

大爆炸

关注公众号「码洞」,让我们来一起聊聊这个框架。

大厨小鲜——自己动手实现一个极简Web框架相关推荐

  1. 大厨小鲜——基于Netty自己动手实现RPC框架

    今天我们要来做一道小菜,这道菜就是RPC通讯框架.它使用netty作为原料,fastjson序列化工具作为调料,来实现一个极简的多线程RPC服务框架. 我们暂且命名该RPC框架为rpckids. 食用 ...

  2. 大厨小鲜——基于Netty自己动手编写RPC框架

    今天我们要来做一道小菜,这道菜就是RPC通讯框架.它使用netty作为原料,fastjson序列化工具作为调料,来实现一个极简的多线程RPC服务框架. 我们暂且命名该RPC框架为rpckids. 食用 ...

  3. 伙伴分配器的一个极简实现

    提起buddy system相信很多人不会陌生,它是一种经典的内存分配算法,大名鼎鼎的Linux底层的内存管理用的就是它.这里不探讨内核这么复杂实现,而仅仅是将该算法抽象提取出来,同时给出一份及其简洁 ...

  4. 很多小伙伴不太了解ORM框架的底层原理,这不,冰河带你10分钟手撸一个极简版ORM框架(赶快收藏吧)

    大家好,我是冰河~~ 最近很多小伙伴对ORM框架的实现很感兴趣,不少读者在冰河的微信上问:冰河,你知道ORM框架是如何实现的吗?比如像MyBatis和Hibernate这种ORM框架,它们是如何实现的 ...

  5. c语言log_Morn:一个极简的C语言日志

    Morn:一个C语言的基础工具和基础算法库​github.com Morn的日志是一个极简的,几乎没有学习成本的日志.它可以实现: 多种输出,包括动态文件.控制台.和用户自定义输出. 日志分级,选择性 ...

  6. 一个极简版本的 VUE SSR demo

    我本人在刚开始看 VUE SSR 官方文档的时候遇到很多问题,它一开始是建立在你有一个可运行的构建环境的,所以它直接讲代码的实现,但是对于刚接触的开发者来说并没有一个运行环境,所以所有的代码片段都无法 ...

  7. 极简linux版本,4MLinux 26.0发布,这是一个极简版本

    4MLinux 26.0版已经发布,这是一个极简版本,包括桌面版(带有JWM)和服务器版(具有完整的LAMP环境). 该项目的最新稳定版本附带升级包以及对现代图像和视频编码的支持: 4MLinux 2 ...

  8. 开源一个极简的群日程工具

    这是一个极简日程小助手,目前以小程序的形式发布.用户喂给它一段文字,它会帮你解析文字里的时间信息,并且创建一个含有通知的日程,用以备忘一些活动或者会议事项. 当然如果你在没有人的环境,你可以直接:

  9. 一个极简、高效的秒杀系统-战略设计篇

    文章目录 一.前言 二.业务需求 2.1 产品需求 2.2 业务流程 2.2.1 秒杀活动整体业务流程 2.2.2 创建秒杀活动 2.2.3 查看秒杀活动 2.2.4 参与秒杀活动 2.2.5 小节 ...

最新文章

  1. BZOJ3110: [Zjoi2013]K大数查询(整体二分)
  2. SPIR-V 研究:编译器基本原理
  3. es ik分词插件安装
  4. lazarus控件怎么那么少_盘点5个常被搞混的控件与规范
  5. 白话Word2Vec
  6. 安装部署elasticsearch过程详解
  7. Windows禁止ping回显
  8. Java 项目的实际开发过程
  9. eclipse如何用php,phpeclipse使用详解
  10. windows xp 美化大师之系统主题
  11. 【学习笔记—eat_pytorch_in_20_days】结构化数据建模流程范例
  12. 12306抢票软件实现(二)
  13. 联通短信息中心号码,联通服务中心号码速查
  14. PNP三极管和NPN三极管的开关电路(EC极性接线判断简单明了)简单的技巧:三极管上箭头所在方向的二极管,只要二极管正向导通,那么三极管上下就能导通。
  15. 2022-4-16 c++ 杂记 mutex GUARDED_BY std::unique_ptr unordered_map ::开头
  16. 概率论复习笔记3.0--假设检验
  17. 形容计算机很烂的网络用语,坑爹什么意思 网络术语坑爹是什么意思?
  18. 微信读书产品体验报告
  19. 唐巧:技术人如何成为管理者
  20. echart 环形饼图设置中心固定信息

热门文章

  1. htmlbiaoge文字居中_css表格文字居中怎么设置?
  2. PPT修改图片大小的三种方法,如何正确的修改图片大小
  3. 物联网与元宇宙融合发展
  4. 京东按关键字搜索商品 API
  5. 苹果内存其他怎么清理_这才是清理苹果手机内存的方法,清理后流畅好几倍,太好用了...
  6. 【20200708】CISA考题练习
  7. 82、PAC-NERF: PHYSICS AUGMENTED CONTINUUM NEURAL RADIANCE FIELDS FOR GEOMETRYAGNOSTIC SYSTEM IDENTIFI
  8. CAD梦想画图中的“复制命令”
  9. 【计算机视觉】TIoU文本检测评价指标
  10. 跨境电商到底应该选择平台还是建独立站(上)