ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

http_router路由匹配深度解析:getHandler与RouterValueSetter提取路径参数全解

http_router路由匹配深度解析:getHandler与RouterValueSetter提取路径参数全解 http_router路由匹配深度解析getHandler与RouterValueSetter提取路径参数全解【免费下载链接】http_router提供标准化的路由注册、路由匹配能力项目地址: https://gitcode.com/Cangjie-SIG/http_router如果你正在用仓颉语言开发 Web 服务http_router就是一个专注于路由匹配的轻量工具给出一条 URL 路径它能帮你快速找到对应的处理器函数并把路径参数如/hello/Alice中的Alice自动提取出来。本文将带你完整看懂两个核心 APIgetHandler如何在路由树中完成一次匹配返回处理器与重定向建议RouterValueSetter如何以key/value回调的形式提取路径参数不需要任何前置经验跟着读就能上手 http_router 是什么http_router 是一个仓颉开源包见 cjpm.toml组织为opencj当前版本 0.1.1参考了业界著名的 httprouter 设计把 Restful 路径解析部分解耦出来只提供两件事能力API说明 路由注册Node.addHandler(path, handler)把路径 → 处理器挂载到路由树 路由匹配Node.getHandler(path, valueSetter)在路由树中查找处理器并提取路径参数处理器类型由泛型T决定你可以传函数、方法甚至自定义类型灵活性很高。完整 API 说明见 README.md。理解路由树Node 的 4 种节点类型http_router 内部把注册过的所有路径组织成一棵路由树每个节点由Node表示。节点类型定义在 NodeType 中共 4 种节点类型含义典型例子Static静态文本节点/file/uploadRoot根节点/Param参数节点:name/hello/:nameCatchAll通配节点*filepath/files/*filepath以注册/hello/:name为例树会被拆成/hello/静态段 :name参数段。理解这一点后匹配过程其实就是从根节点一路向下走树的过程。getHandler一行调用完成路由匹配核心签名定义在 node.cj#L296-L305public func getHandler(path: String, valueSetter: ?RouterValueSetter): (?T, Bool)返回值是一个二元组初学者最容易困惑的就是它?T可空的处理器匹配成功返回对应处理器没匹配到返回NoneBool尾斜杠重定向建议路径本身没命中但加个/或去掉/就能命中时为true方便你给出 301 重定向提示内部实现getHandlerWalk会循环消费剩余路径逐段比对节点当请求路径和当前节点路径完全相等时即完成匹配。整个过程没有字符串遍历开销是典型的前缀树Trie查找思路。RouterValueSetter路径参数提取全解RouterValueSetter的类型定义非常简单见 types.cj#L33public type RouterValueSetter (key: String, value: String) - Unit它本质是一个回调函数匹配过程中每遇到一个路径参数路由树就会带着参数名和参数值调用你。参数节点:name如何触发当你用getHandler(/hello/changeden, setter)匹配已注册的/hello/:name时走到Param节点会执行 node.cj#L345-L347 的逻辑keyname冒号后的参数名valuechangedenURL 中该段的实际内容也就是说你不需要自己写任何解析代码参数在匹配的瞬间就被送进了回调。通配节点*filepath如何触发通配参数会捕获剩余全部路径。在CatchAll分支见 node.cj#L374-L380例如注册/files/*filepath请求/files/a/b.png时keyfilepathvaluea/b.png一个直观的例子func getDefaultValueSetter(route: String): RouterValueSetter { { key, value println([${route}] key: ${key} , value: ${value}) } }这段代码来自 main.cj#L77-L81。注册/hello/:name后请求/hello/changeden控制台就会打印[hello] key: name , value: changeden这就是匹配 参数提取一次调用完成的效果。实战多请求方法的路由匹配实际 Web 服务中同一个路径往往对应不同的请求方法GET/POST/PUT。main.cj 给出了完整的多节点示例用HashMapHttpMethod, NodeHandler为每种方法维护一棵独立的路由树。func registerHandler(rootMap: HashMapHttpMethod, NodeDefaultHandler, method: HttpMethod, path: String, h: DefaultHandler): Unit { if (!rootMap.contains(method)) { rootMap[method] NodeDefaultHandler() } rootMap[method].addHandler(path, h) }匹配时先用方法查到对应树再调用getHandler即可见 main.cj#L69-L75。HttpMethod枚举定义在同文件 L26-L59你可以按需扩展方法类型。开发调试时强烈推荐用 dump 打印整棵路由树直观查看节点划分与类型dump(root)避坑指南注册时的冲突规则http_router 对非法路由会直接panic抛异常把错误挡在启动阶段。以下是四条高频规则同一路径重复注册一个路径只能挂一个处理器重复注册直接报错node.cj#L167-L170一个路径段只允许一个通配符/:a:b是非法的node.cj#L195-L203通配符必须命名/:这种空名字不允许node.cj#L212-L215CatchAll 只能放在路径末尾/files/*filepath✅/*filepath/files❌node.cj#L247-L250 另外注意通配符与静态子节点会冲突——如果/user已注册子路由再注册/user/:id会 panicnode.cj#L205-L210。设计 URL 时让参数段与静态段错开即可。快速上手3 步跑起来第一步获取源码git clone https://gitcode.com/Cangjie-SIG/http_router第二步构建项目项目使用 cjpm 管理见 cjpm.toml要求仓颉编译器 1.1.0cjpm build第三步注册 匹配 提取参数参考 README.md 单节点示例let root NodeDefaultHandler() root.addHandler(/, index) root.addHandler(/hello/:name, hello) let (handler, _) root.getHandler(/hello/changeden, getDefaultValueSetter(hello)) handler?()三步完成路由注册、路由匹配、参数提取的完整闭环 总结要点一句话记忆NodeT路由树节点泛型决定处理器类型addHandler把路径挂到树上冲突直接 panicgetHandler走树匹配返回(处理器, 尾斜杠建议)RouterValueSetter(key, value)回调自动提取:name与*filepath参数dump调试利器一眼看清路由树结构http_router 的设计哲学是少即是多不含 HTTP 框架的包袱只把路由注册与匹配做到标准、快速、可组合。无论是嵌入你自己的 Web 框架还是做工具类应用它都是一个干净可靠的底层构件。【免费下载链接】http_router提供标准化的路由注册、路由匹配能力项目地址: https://gitcode.com/Cangjie-SIG/http_router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表