首先我们看看这个 Web 框架使用起来如何简单
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
关注公众号「码洞」,让我们来一起聊聊这个框架。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.