使用 Java 语言基于 Netty 自己动手实现一个极简 web 框架 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
codehole
V2EX    程序员

使用 Java 语言基于 Netty 自己动手实现一个极简 web 框架

  •  
  •   codehole
    pyloque 2018-04-24 16:46:58 +08:00 3026 次点击
    这是一个创建于 2778 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上节课我们自己动手制作了一个 RPC 框架,本节课我们挑战一个稍有难度的一点的任务,手动制作一个 Web 框架。 我不太愿意叫什么 MVC 框架,因为我在制作这个小项目的时候可没想过它要怎么怎么的 MVC,一切皆以易于使用为目标。

    首先我们看看这个 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 的调用栈,我们来看看它到底有多深

    项目代码

    HttpKids Web Framework based on Netty for Kids of You

    RpcKids RPC Framework based on Netty for Kids of You

    大爆炸

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

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4128 人在线   最高记录 6679       Select Language
    意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 05:31 PVG 13:31 LAX 21:31 JFK 00:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86