Gin 路由添加流程

简介: Gin 路由添加流程
  1. 计算 absolutePath
  2. 业务 HandlerFunc 与中间件 HandlerFunc 组合
  3. Engine methodTrees 添加路由
  • methodTrees 实际上是 methodTree 组成的森林,每个 methodTree 是一颗 HTTP 方法的树
  • Engine.addRoute
func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { assert1(path[0] == '/', "path must begin with '/'") assert1(method != "", "HTTP method can not be empty") assert1(len(handlers) > 0, "there must be at least one handler")
  debugPrintRoute(method, path, handlers)
  root := engine.trees.get(method)//是否有HTTP方法的路由树 if root == nil {//没有 构建根节点    root = new(node)    root.fullPath = "/"   engine.trees = append(engine.trees, methodTree{method: method, root: root}) } root.addRoute(path, handlers)
  // Update maxParams if paramsCount := countParams(path); paramsCount > engine.maxParams {   engine.maxParams = paramsCount  }
  if sectionsCount := countSections(path); sectionsCount > engine.maxSections {   engine.maxSections = sectionsCount  }}


  • node.addRoute
func (n *node) addRoute(path string, handlers HandlersChain) {  fullPath := path  n.priority++
  // Empty tree if len(n.path) == 0 && len(n.children) == 0 {   n.insertChild(path, fullPath, handlers)   n.nType = root    return  }
  parentFullPathIndex := 0
walk: for {   // Find the longest common prefix.    // This also implies that the common prefix contains no ':' or '*'    // since the existing key can't contain those chars.    i := longestCommonPrefix(path, n.path)
    // Split edge   if i < len(n.path) {      child := node{        path:      n.path[i:],        wildChild: n.wildChild,       indices:   n.indices,       children:  n.children,        handlers:  n.handlers,        priority:  n.priority - 1,        fullPath:  n.fullPath,      }
      n.children = []*node{&child}      // []byte for proper unicode char conversion, see #65     n.indices = bytesconv.BytesToString([]byte{n.path[i]})      n.path = path[:i]     n.handlers = nil      n.wildChild = false     n.fullPath = fullPath[:parentFullPathIndex+i]   }
    // Make new node a child of this node   if i < len(path) {      path = path[i:]     c := path[0]
      // '/' after param      if n.nType == param && c == '/' && len(n.children) == 1 {       parentFullPathIndex += len(n.path)        n = n.children[0]       n.priority++        continue walk     }
      // Check if a child with the next path byte exists      for i, max := 0, len(n.indices); i < max; i++ {       if c == n.indices[i] {          parentFullPathIndex += len(n.path)          i = n.incrementChildPrio(i)         n = n.children[i]         continue walk       }     }
      // Otherwise insert it      if c != ':' && c != '*' && n.nType != catchAll {        // []byte for proper unicode char conversion, see #65       n.indices += bytesconv.BytesToString([]byte{c})       child := &node{         fullPath: fullPath,       }       n.addChild(child)       n.incrementChildPrio(len(n.indices) - 1)        n = child     } else if n.wildChild {       // inserting a wildcard node, need to check if it conflicts with the existing wildcard        n = n.children[len(n.children)-1]       n.priority++
        // Check if the wildcard matches        if len(path) >= len(n.path) && n.path == path[:len(n.path)] &&          // Adding a child to a catchAll is not possible         n.nType != catchAll &&          // Check for longer wildcard, e.g. :name and :names         (len(n.path) >= len(path) || path[len(n.path)] == '/') {          continue walk       }
        // Wildcard conflict        pathSeg := path       if n.nType != catchAll {          pathSeg = strings.SplitN(pathSeg, "/", 2)[0]        }       prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path        panic("'" + pathSeg +         "' in new path '" + fullPath +          "' conflicts with existing wildcard '" + n.path +         "' in existing prefix '" + prefix +         "'")      }
      n.insertChild(path, fullPath, handlers)     return    }
    // Otherwise add handle to current node   if n.handlers != nil {      panic("handlers are already registered for path '" + fullPath + "'")    }   n.handlers = handlers   n.fullPath = fullPath   return  }}



目录
相关文章
|
8月前
|
人工智能 JavaScript API
【HarmonyOS NEXT+AI】问答03:找不到DevEco Studio Cangjie Plugin下载链接?
本文针对学员在“HarmonyOS NEXT+AI大模型打造智能助手APP(仓颉版)”课程中提出的问题进行解答:为何无法在华为开发者社区官网找到DevEco Studio Cangjie Plugin下载链接。文中详细介绍了Cangjie Plugin的功能及获取方式,包括STS和Canary版本的申请流程,并提供了学习仓颉编程语言的资源与建议。对于普通开发者,STS版本是当前首选;同时,通过课程与官方教程,可快速掌握仓颉语言核心语法及API,助力开发HarmonyOS NEXT AI智能助手应用。
461 3
【HarmonyOS NEXT+AI】问答03:找不到DevEco Studio Cangjie Plugin下载链接?
|
Python
NumPy 教程 之 NumPy 算术函数 1
本教程介绍NumPy中的基本算术函数,如加(add())、减(subtract())、乘(multiply())及除(divide())。示例展示了两个数组(一个3x3矩阵与一数组[10,10,10])间的运算。值得注意的是,参与运算的数组需有相同形状或可按照NumPy的广播规则进行扩展。此外Numpy还提供了许多其他的算术函数以满足复杂计算需求。
170 7
|
10月前
|
人工智能 自然语言处理 供应链
国产与国外CRM系统:功能与优势全解析
随着企业数字化转型加速,CRM系统成为提升竞争力的关键工具。国产CRM系统如销售易、神州云动、八骏科技等,以高性价比、本地化服务和灵活定制见长;国外CRM系统如Salesforce、Zoho CRM、Microsoft Dynamics 365等,则在功能创新、全球化支持和技术成熟度上表现突出。企业在选择时应综合考虑自身需求,选取最适合的CRM系统,助力业务高质量增长。
|
机器学习/深度学习 算法 数据可视化
8种数值变量的特征工程技术:利用Sklearn、Numpy和Python将数值转化为预测模型的有效特征
特征工程是机器学习流程中的关键步骤,通过将原始数据转换为更具意义的特征,增强模型对数据关系的理解能力。本文重点介绍处理数值变量的高级特征工程技术,包括归一化、多项式特征、FunctionTransformer、KBinsDiscretizer、对数变换、PowerTransformer、QuantileTransformer和PCA,旨在提升模型性能。这些技术能够揭示数据中的潜在模式、优化变量表示,并应对数据分布和内在特性带来的挑战,从而提高模型的稳健性和泛化能力。每种技术都有其独特优势,适用于不同类型的数据和问题。通过实验和验证选择最适合的变换方法至关重要。
501 6
8种数值变量的特征工程技术:利用Sklearn、Numpy和Python将数值转化为预测模型的有效特征
|
存储 编解码 数据可视化
Visium HD空间数据分析、可视化以及整合 (1)
【8月更文挑战第1天】Visium HD空间数据分析、可视化以及整合 (1)
Visium HD空间数据分析、可视化以及整合 (1)
|
运维 网络协议 网络安全
2023网络建设与运维正式赛卷-交换配置
【7月更文挑战第3天】某集团构建了两地三中心网络架构,包括两个数据中心和异地灾备中心,使用OSPF、RIP、ISIS、BGP协议互联。核心设备包括SW1、SW2(数据中心)、SW3(灾备及办事处),以及FW1(总司防火墙)、FW2(办事处防火墙)等。网络拓扑涉及多个VLAN和IP地址段,SW3配置了VRF隔离办事处和Internet流量。SW1配置SNMPv3用于监控,并设置流量镜像。链路故障检测和LLDP启用以确保网络健康。
|
人工智能
AI智能外呼okcc呼叫中心外呼的几种形式
外呼系统,很多人喜欢称呼为电销系统。那么今天我们就按照这个称呼来分享下外呼的几种形式。当然,OKCC不只是一套外呼系统,而是一套完整的呼叫中心系统,呼出呼入都可以实现。只是目前客户群体比较多的,是外呼这个场景占多数。 虽然外呼市场都已经卷坏了,但是还是有新入行的通讯人,他只知道他要干这个事情,但是客户的外呼场景他搞不明白,那么今天就详细讲讲,希望能帮助到这些新入行的通讯伙伴。 1. 点击外呼 最基本功能,也是最常用的。 系统具有电话工具条,可以输入被叫号码,点击拨号进行呼叫。 这种方式需要座席人员手工输入或者粘贴号码到输入框,当企
|
文字识别 前端开发 JavaScript
Star33.1k!推荐一个基于网页的OCR(光学字符识别)引擎库
想要在前端解决图像识别的兄弟,可以到 Github 上下载Tesseract.js库,安装和相关学习文档都能下载到,实在获取不到的兄弟找V哥发给你,假期第二天,出去放松的同时也可以看看 V 哥的文章,祝大家玩得开心。
471 0
|
缓存 负载均衡 安全
每天一技:全面了解CC攻击和防范策略
CC攻击是一种模拟真实用户请求,导致服务器资源耗尽的网络攻击。攻击者利用工具生成木马,控制大量“肉鸡”对目标网站发起恶意请求,使服务器CPU过载,网站无法正常服务。特点是请求有效、IP分散、数据包真实、针对网页。常见类型包括直接攻击、肉鸡攻击、僵尸攻击和代理攻击。判断CC攻击可通过观察CPU usage飙升和系统日志异常。大型网站如某度、Google因代码规范、硬件配置高、缓存策略、严格防火墙和负载均衡等技术能有效防御。防御措施包括IP封禁、人机验证、静态化页面、更改Web端口、日志分析等,或使用SCDN产品提供全面防护,包括Web攻击防护、DDoS防护、合规性保障、流量管理和安全可视化功能。
|
存储 数据可视化
使用 plotly 绘制旭日图
使用 plotly 绘制旭日图
746 0