Router 路由组件
让我们一起来探索 Feat 框架中强大的 Router 组件!它就像一个聪明的交通警察,能够准确地将每个 HTTP 请求引导到正确的处理程序。当你的应用程序逐渐变得复杂,拥有越来越多的 API 接口时,Router 就是你管理这些接口的得力助手。
Router 是什么?
Section titled “Router 是什么?”Router 组件是 Feat 框架中负责 HTTP 请求路由分发的核心组件。它不仅能根据请求路径将请求分发到对应的处理器,还提供了 Session 管理、请求拦截等强大功能。
想象一下,当你的应用程序有成百上千个不同的 API 接口时,如果没有一个好的路由机制,代码将会变得多么混乱!而 Router 正是解决这个问题的利器。
让我们从一个简单的例子开始,看看如何使用 Router 创建一个基础的 Web 服务:
// 实践导向的示例:展示如何创建带有路由的HTTP服务public class RouterDemo { public static void main(String[] args) { // 创建路由管理器 Router router = new Router();
// 配置一个简单的路由 router.route("/", ctx -> { ctx.Response.write("欢迎来到 Feat Router 世界!"); });
// 启动服务器并使用路由管理器 Feat.httpServer() .httpHandler(router) .listen(8080); }}这段代码展示了 Router 的基本用法。我们创建了一个 Router 实例,配置了一个处理根路径 / 的路由,然后将其作为 HTTP 处理器传递给服务器。
路由匹配详解
Section titled “路由匹配详解”Router 支持多种路由匹配模式,让你能够灵活地定义 API 接口。
精确路径匹配
Section titled “精确路径匹配”最简单的匹配方式是精确路径匹配,适用于固定路径的接口:
router.route("/user/profile", ctx -> { ctx.Response.write("用户档案页面");});路径参数匹配
Section titled “路径参数匹配”当需要从 URL 中提取参数时,可以使用路径参数匹配:
router.route("/user/:id", ctx -> { // 从路径中提取 id 参数 String userId = ctx.pathParam("id"); ctx.Response.write("用户ID: " + userId);});对于需要匹配多个路径的情况,可以使用通配符:
// 匹配 /static/ 下的所有路径router.route("/static/*", ctx -> { ctx.Response.write("静态资源处理");});当多个路由规则可能匹配同一个请求时,Router 会按照以下优先级进行匹配:
- 精确路径匹配(最高优先级)
- 路径参数匹配
- 通配符匹配(最低优先级)
来看一个形象的路由匹配示意图:
会话管理(Session)
Section titled “会话管理(Session)”Router 内置了 Session 管理功能,让你能够轻松地在用户请求之间保持状态。
配置 Session
Section titled “配置 Session”可以通过 SessionOptions 配置 Session 的行为:
Router router = new Router();// 设置 Session 最大存活时间(秒)router.getSessionOptions().setMaxAge(1800); // 30分钟使用 Session
Section titled “使用 Session”在请求处理中可以方便地使用 Session:
// 创建 Session 并存储数据router.route("/login", ctx -> { // 获取或创建 Session Session session = ctx.session(); // 设置 Session 属性 session.put("userId", "12345"); session.put("username", "张三"); ctx.Response.write("登录成功");});
// 读取 Session 数据router.route("/profile", ctx -> { Session session = ctx.session(); // 获取 Session 但不创建 if (session != null) { String username = (String) session.get("username"); ctx.Response.write("欢迎," + username); } else { ctx.Response.setHttpStatus(HttpStatus.UNAUTHORIZED); ctx.Response.write("请先登录"); }});
// 销毁 Sessionrouter.route("/logout", ctx -> { Session session = ctx.session(); if (session != null) { // 手动使 Session 失效 session.invalidate(); } ctx.Response.write("已退出登录");});Session 的生命周期管理示意图:
拦截器允许你在请求处理前后执行自定义逻辑,比如权限验证、日志记录等。这就像在请求处理流水线上设置检查点一样。
实现 Interceptor 接口创建自定义拦截器:
public class LogInterceptor implements Interceptor { @Override public void intercept(Context ctx, CompletableFuture<Void> completableFuture, Chain chain) throws Throwable { System.out.println("请求开始: " + ctx.Request.getRequestURI()); try { // 继续执行后续的拦截器或目标处理器 chain.proceed(ctx, completableFuture); } finally { System.out.println("请求结束: " + ctx.Request.getRequestURI()); } }}通过 addInterceptor 方法为特定路径模式配置拦截器:
Router router = new Router();// 为所有 /api 路径下的请求添加日志拦截器router.addInterceptor("/api/*", new LogInterceptor());
// 为管理接口添加权限验证拦截器router.addInterceptor("/admin/*", new AuthInterceptor());拦截器执行流程如下:
让我们通过一个完整的示例来看看 Router 的各种功能是如何协同工作的:
public class CompleteRouterDemo { public static void main(String[] args) { Router router = new Router();
// 配置 Session router.getSessionOptions().setMaxAge(1800); // 30分钟
// 添加日志拦截器 router.addInterceptor("/*", (ctx, future, chain) -> { long start = System.currentTimeMillis(); System.out.println("开始处理请求: " + ctx.Request.getRequestURI()); try { chain.proceed(ctx, future); } finally { long end = System.currentTimeMillis(); System.out.println("请求处理完成,耗时: " + (end - start) + "ms"); } });
// 配置路由 router.route("/", ctx -> { ctx.Response.write("欢迎使用 Feat Router!"); });
// Session 示例 router.route("/login", ctx -> { Session session = ctx.session(); session.put("loginTime", System.currentTimeMillis()); session.put("username", "张三"); ctx.Response.write("登录成功"); });
router.route("/user/:id", ctx -> { String id = ctx.pathParam("id"); Session session = ctx.session(); // 获取 Session 但不创建 if (session != null) { Long loginTime = (Long) session.get("loginTime"); ctx.Response.write("用户 " + id + ",登录时间: " + loginTime); } else { ctx.Response.setHttpStatus(HttpStatus.UNAUTHORIZED); ctx.Response.write("请先登录"); } });
// 通配符匹配示例 router.route("/api/*", ctx -> { ctx.Response.write("API 接口处理: " + ctx.Request.getRequestURI()); });
// 启动服务器 Feat.httpServer() .httpHandler(router) .listen(8080); }}有关完整示例,请参见 RouterSessionDemo.java
HTTP 方法支持
Section titled “HTTP 方法支持”Router 还支持针对不同 HTTP 方法的路由配置:
// 为 GET 请求配置路由router.route("/user", "GET", ctx -> { ctx.Response.write("获取用户列表");});
// 为 POST 请求配置路由router.route("/user", "POST", ctx -> { ctx.Response.write("创建新用户");});
// 为多个 HTTP 方法配置同一个处理器router.route("/user/:id", new String[]{"PUT", "PATCH"}, ctx -> { String userId = ctx.pathParam("id"); ctx.Response.write("更新用户: " + userId);});Feat Router 组件提供了一套完整的 HTTP 路由解决方案,具有以下优势:
- 高性能:基于前缀树的路由匹配算法,提供高效的路由查找性能
- 灵活性:支持多种路由匹配模式,满足不同业务场景需求
- 易用性:链式调用 API 设计,简化路由配置
- 扩展性:支持拦截器机制,方便添加自定义处理逻辑
- 内置功能:集成 Session 管理,无需额外配置
通过合理使用 Router 组件,可以快速构建功能丰富、性能优良的 Web 应用。在实际开发中,建议结合具体业务场景,合理规划路由结构,充分发挥 Router 的强大功能。
掌握了这些基础,你就能轻松应对大部分路由场景了。接下来不妨尝试创建一个自己的 Web 服务,体验一下 Router 的强大功能吧!