前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大厨小鲜——自己动手实现一个极简Web框架

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

作者头像
老钱
发布2018-08-14 17:44:07
5470
发布2018-08-14 17:44:07
举报
文章被收录于专栏:码洞码洞

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

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

Hello World

代码语言:javascript
复制
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框架来管理。

一个全面的例子

代码语言:javascript
复制
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 Web Framework based on Netty for Kids of You

https://github.com/pyloque/rpckids RPC Framework based on Netty for Kids of You

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码洞 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Hello World
  • 一个全面的例子
  • 堆栈深度
  • 项目代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档