商业公链之区块链技术使用的常见库(九)------Go语言http路由库"github.com/gorilla/mux"

2023-10-27

目录

介绍

安装

使用

常用方法介绍

1.初始化路由

2.路由注册

3.子路由的使用

4.定义路由别名

5.静态文件路由

7.生成已注册的URL

8.Walk方法

9.Middleware 中间件

10.开启监听端口:

11.get请求处理:

12.post请求处理

测试

Get请求

Post请求

综合示例


介绍

mux 是一个用来执行http请求的路由和分发的第三方扩展包。mux 其名称来源于HTTP request multiplexer,类似于官方包http.ServeMuxmux.Router将会定义一个路由列表,其中每一个路由都会定义对应的请求url,及其处理方法。

安装

go get -u github.com/gorilla/mux

使用

添加包引用:

import "github.com/gorilla/mux"

常用方法介绍

1.初始化路由

r := mux.NewRouter()

路由路径重定向,StrictSlash如果为true,则如果路由路径为“/path/”,则访问“/path”将执行到前者的重定向,反之亦然。

StrictSlash(true)

2.路由注册

最简单的路由注册:

r.HandleFunc("/", HomeHandler)

其中代码中的第一个参数为请求url,第二个参数为请求的处理函数,该函数可简单的定义为以下代码:

func HomeHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "this is home")
}

带有变量的url路由注册:
其中参数可使用正则表达式匹配

r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)

指定Host:

r.Host("www.example.com")

指定http方法:

r.Methods("GET", "POST")

指定URL安全策略:

r.Schemes("https")

增加URL前缀:

r.PathPrefix("/products/")

添加请求头:

r.Headers("X-Requested-With", "XMLHttpRequest")

添加请求参数:

r.Queries("key", "value")

组合使用:

r.HandleFunc("/products", ProductsHandler).
  Host("www.example.com").
  Methods("GET").
  Schemes("http")

3.子路由的使用

r := mux.NewRouter()
s := r.PathPrefix("/products").Subrouter()
// "/products/"s.HandleFunc("/", ProductsHandler)
// "/products/{key}/"s.HandleFunc("/{key}/", ProductHandler)
// "/products/{key}/details"s.HandleFunc("/{key}/details", ProductDetailsHandler)

4.定义路由别名

r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).Name("article")

5.静态文件路由

flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
flag.Parse()
r := mux.NewRouter() // This will serve files under http://localhost:8000/static/<filename>
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

7.生成已注册的URL

生成已注册的url需要用到路由的别名,代码如下:

url, err := r.Get("router_name").URL("key1", "val1", "key2", "val2")

例如:

r := mux.NewRouter()
r.Host("{subdomain}.domain.com").
  Path("/articles/{category}/{id:[0-9]+}").
  Queries("filter", "{filter}").
  HandlerFunc(ArticleHandler).
  Name("article")

// url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla"
url, err := r.Get("article").URL("subdomain", "news",
                                 "category", "technology",
                                 "id", "42",
                                 "filter", "gorilla")

8.Walk方法

walk方法可以遍历访问所有已注册的路由,例如以下代码:

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", handler)
    r.HandleFunc("/products", handler).Methods("POST")
    r.HandleFunc("/articles", handler).Methods("GET")
    r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
    r.HandleFunc("/authors", handler).Queries("surname", "{surname}")
    err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
        pathTemplate, err := route.GetPathTemplate()        if err == nil {
            fmt.Println("ROUTE:", pathTemplate)
        }
        pathRegexp, err := route.GetPathRegexp()        if err == nil {
            fmt.Println("Path regexp:", pathRegexp)
        }
        queriesTemplates, err := route.GetQueriesTemplates()        if err == nil {
            fmt.Println("Queries templates:", strings.Join(queriesTemplates, ","))
        }
        queriesRegexps, err := route.GetQueriesRegexp()        if err == nil {
            fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ","))
        }
        methods, err := route.GetMethods()        if err == nil {
            fmt.Println("Methods:", strings.Join(methods, ","))
        }
        fmt.Println()        return nil
    })    if err != nil {
        fmt.Println(err)
    }

    http.Handle("/", r)
}

9.Middleware 中间件

mux同样也支持为路由添加中间件。

最简单的中间件定义:

func loggingMiddleware(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        // Do stuff here
        log.Println(r.RequestURI)        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}

中间件使用:

r := mux.NewRouter()
r.HandleFunc("/", handler)
r.Use(loggingMiddleware)

10.开启监听端口:

err := http.ListenAndServe(address, router)

11.get请求处理:

  //响应数据
   var res map[string]string = make(map[string]string)
   var status = http.StatusOK   
   //获得请求参数
   vals := r.URL.Query()
  //获得参数name对应的值
   param, ok := vals["name"]
   if (!ok) {
      res["result"] = "fail"
      res["error"] = "required parameter name is missing"
      status = http.StatusBadRequest
   } else {
      res["result"] = "succ"
      res["name"] = param[0]
      status = http.StatusOK
   }
   //序列化
   response, _ := json.Marshal(res)
   //响应成功写入头部
   w.WriteHeader(status)
   //设置返回格式
   w.Header().Set("Content-Type", "application/json")
  //写入数据
   w.Write(response)
}

12.post请求处理

vars := mux.Vars(r)
   servicename := vars["servicename"]
   // parse JSON body
   var req map[string]interface{}
   //读取body
   body, _ := ioutil.ReadAll(r.Body)
   //fmt.Println(r.Body)
   json.Unmarshal(body, &req)
  //获得body参数对应字符串值
   servicetype := req["servicetype"].(string)
   // composite response body
   var res = map[string]string{"result":"succ", "name":servicename, "type":servicetype}
   response, _ := json.Marshal(res)
   w.Header().Set("Content-Type", "application/json")
   w.Write(response)

测试

Postman插件:一种网页调试与发送网页http请求的chrome插件,很方便的模拟get或者post或其他方式的请求来调试接口。模拟用户HTTP请求的数据发送到服务器,以便开发人员能够及时地作出正确的响应,或者是对产品发布之前的错误信息提前处理,进而保证产品上线后的稳定性和安全性。下载链接:https://www.getpostman.com/downloads/

Get请求


①在地址栏里输入请求url:http://localhost:8080/api/service/get
②选择“GET”方式,点击"Params",添加添加 key和 value
③点击“send”得到数据

如图:

Post请求


①在地址栏里输入请求url:http://localhost:8080/api/service/myservice/post

②在Body下选择“Raw”,在编辑框中输入你需要提交的参数的键和值,点击“send”提交请求

POST-JSON方式提交
①如果服务端需要请求类型为json,需要在“headers”添加
key:Content-Type , value:application/json
②可先在Body下的选项中点击“Raw”,在右边下拉三角选择“json”,此时第一步中Header需要设置的会自动添加

 

综合示例

package th_muximport(    "strings"
    "flag"
    "fmt"
    "net/http"
    "github.com/gorilla/mux")func Run(){
    var dir string
    flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
    flag.Parse()    // 初始化Router
    r := mux.NewRouter()    // 静态文件路由
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))    // 普通路由
    r.HandleFunc("/", HomeHandler)    // 指定host
    r.HandleFunc("/host", HostHandler).Host("localhost")    // 带变量的url路由
    r.HandleFunc("/users/{id}", GetUserHandler).Methods("Get").Name("user")

    url, _ := r.Get("user").URL("id", "5")
    fmt.Println("user url: ", url.String())    // 遍历已注册的路由
    r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
        pathTemplate, err := route.GetPathTemplate()        if err == nil {
            fmt.Println("ROUTE:", pathTemplate)
        }
        pathRegexp, err := route.GetPathRegexp()        if err == nil {
            fmt.Println("Path regexp:", pathRegexp)
        }
        queriesTemplates, err := route.GetQueriesTemplates()        if err == nil {
            fmt.Println("Queries templates:", strings.Join(queriesTemplates, ","))
        }
        queriesRegexps, err := route.GetQueriesRegexp()        if err == nil {
            fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ","))
        }
        methods, err := route.GetMethods()        if err == nil {
            fmt.Println("Methods:", strings.Join(methods, ","))
        }
        fmt.Println()        return nil
    })

    r.Use(TestMiddleware)
    http.ListenAndServe(":3000", r)
}func HomeHandler(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "this is home")
}func HostHandler(w http.ResponseWriter, r *http.Request){
    w.WriteHeader(http.StatusOK)
    fmt.Fprintf(w, "the host is localhost")
}func GetUserHandler(w http.ResponseWriter, r *http.Request){
    vars := mux.Vars(r)
    w.WriteHeader(http.StatusOK)
    
    fmt.Fprint(w, "this is get user, and the user id is ", vars["id"])
}func TestMiddleware(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        // Do stuff here
        fmt.Println("middleware print: ", r.RequestURI)        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}

运行结果截图
刚执行时的注册打印:

注册

依次在浏览器中输入以下地址测试,查看结果:
http://localhost:3000/
hosthttp://127.0.0.1:3000/
hosthttp://localhost:3000/users/5

示例源码:阅读原文,用法文档:https://godoc.org/github.com/gorilla/mux

希望大家关注我的微信公众号,推荐给更多技术极客,日更一篇区块链技术博客不易,有疑问可以后台留言。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

商业公链之区块链技术使用的常见库(九)------Go语言http路由库"github.com/gorilla/mux" 的相关文章

  • 如何将 int[] 转换为 uint8[]

    所以 我需要你的帮助 我找不到关于该主题的任何内容 Golang 是一门刚刚诞生的语言 所以对于像我这样的新手来说很难快速找到答案 预先声明的 Goint类型大小是特定于实现的 32 位或 64 位 数字类型 http golang org
  • Golang:带有 JSON 负载的 http.NewRequest POST 返回错误 500

    我正在开发一个 API 库 有一个API端点 POST 当您发出curl命令时 它是 curl H X API TOKEN API TOKEN http interest graph getprismatic com text topic
  • 将 time.Time 转换为字符串

    我正在尝试将数据库中的一些值添加到 string在围棋中 其中一些是时间戳 我收到错误 无法在数组元素中使用 U Created date 类型 time Time 作为类型字符串 我可以转换吗time Time to string typ
  • os.Mkdir 和 os.MkdirAll 权限

    我正在尝试在程序开始时创建一个日志文件 我需要检查是否 log如果不创建目录 则目录存在 然后继续创建日志文件 好吧 我尝试使用os Mkdir 也os MkdirAll 但无论我在第二个参数中输入什么值 我都会得到一个没有权限的锁定文件夹
  • select 语句是否保证通道选择的顺序?

    继从这个答案 https stackoverflow com a 25795236 274460 如果一个 goroutine 在两个通道上进行选择 是否保证通道的选择顺序与其发送的顺序相同 我对发送者是单线程的情况特别感兴趣 例如 是否保
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute
  • 如何修复“缺少表的 FROM 子句条目”错误

    我正在尝试根据游戏 ID 获取平台名称 我有如下三个表 我正在尝试加入它们以获得所需的结果 Games Id 1 2 3 4 Game Platforms Id game id platform id 1 1 1 2 1 2 3 3 3
  • 如何将接口转换为接口切片?

    我的输入是interface 而且我知道它可以是任何类型的数组 我想读取我输入的元素之一 所以我尝试将我的interface 进入一个 interface 但是 go 会给我以下错误 恐慌 接口转换 interface 是 map stri
  • 是否可以在 C/C++ 中模仿 Go 接口?

    在 Go 中 如果类型具有接口定义的所有方法 则可以将其分配给该接口变量 而无需显式继承它 是否可以在 C C 中模仿此功能 是的 您可以使用纯抽象类 并使用模板类来包装 实现 抽象类的类型 以便它们扩展抽象类 这是一个简单的示例 incl
  • 什么时候返回结构体指针是个好主意?

    我正在学习 Go 我对何时使用指针有点困惑 具体来说 当返回一个struct从函数中 什么时候适合返回结构体实例本身 什么时候适合返回指向结构体的指针 示例代码 type Car struct make string model strin
  • GoLang 中的 HTML 部分

    我刚刚开始使用 Go 我想用它创建一个网络应用程序 我现在尝试的是以handlebarsjs 式的方式使用模板 我想将页眉和页脚从主页中取出 以便可以将它们注入到每个网页上 我当前的设置应该是解析主页 页眉和页脚 HTML 文件并缓存它们
  • 将产生 goroutine 的 golang 方法

    据我所知 如果 goroutine 太忙 它们会阻止其他 goroutine 运行 对我来说 这意味着我的应用程序的性能和响应能力可能取决于我知道哪些库方法将控制其他 goroutine 例如通常是 Read 和 Write 有什么方法可以
  • 当使用 k8s.io/client-go 库的 kubernetes 部署发生更改时获得通知的最佳方式是什么?

    Context 我正在编写一个使用k8s io client go https github com kubernetes client go 图书馆 这里是 godocs https godoc org k8s io client go
  • 使用泛型:类型参数 T 不能与 == 进行比较

    我正在操场上玩 Go Generics 尝试编写一些通用数组函数 https gotipplay golang org p vS7f Vxxy2j https gotipplay golang org p vS7f Vxxy2j packa
  • 指针上定义的方法仍然可以用值调用

    Effective Go 文档说明如下 关于接收者的指针与值的规则是 可以在指针和值上调用值方法 但只能在指针上调用指针方法 http tip golang org doc effective go html pointers vs val
  • 关于编写惯用的 Golang 的建议

    我正在掌握 Golang 的做事方式 首先是一些示例代码 package main import log os func logIt s string f os OpenFile errors log os O RDWR os O CREA
  • 如何在 Go 中使用与包同名的变量名?

    文件或目录的常见变量名称是 path 不幸的是 这也是 Go 中包的名称 此外 在 DoIt 中更改路径作为参数名称 如何编译此代码 package main import path os func main DoIt file txt f
  • Golang:如何在HTTP客户端的TLS配置中指定证书

    我有一个证书文件 该位置是 usr abc my crt我想将该证书用于我的 tls 配置 以便我的 http 客户端在与其他服务器通信时使用该证书 我当前的代码如下 mTLSConfig tls Config CipherSuites u
  • 重新设计循环依赖缺陷

    我有一堆小服务 它们共享一些常见的包 例如Logger Configuration and Net 我在单独的项目中编写了每个包 问题是我的Logger需求包Configuration用于设置 和我的Configuration not仅由L
  • []interface{}{} 中的双大括号是什么意思

    请注意 这是格式为 的双花括号 而不是嵌套花括号 我也不确定这是空接口问题 切片问题还是结构问题 我猜它至少是其中两个的组合 我正在学习 Golang 并且已经达到了空接口 我发现我需要将空接口声明为 interface 或者例如 inte

随机推荐

  • 修改Jupyter Notebook默认目录

    Jupyter Notebook介绍 通过网页访问的web应用程序 在网页中编写和执行程序 便于程序的远程访问 屏蔽了不同系统间的显示差异 能够通过网页或PPT的方式分享 可以在同一个文档中展示代码 图像 注释 公式 图形和运行结果 初次安
  • Microsoft Dynamics CRM 服务器安装说明

  • LCD1602 液晶显示实验

    LCD1602 简介 LCD1602是一种用来显示字母 数字 符号的点阵型液晶模块 可显示 2 行字符信息 每行又能显示 16 个字符 每个字符由若干个 5x7 或 5x10 的点阵字符位组成 每位之间有一个点距的间隔 每行之间也有间隔 起
  • linux给脚本文件赋权限,linux编写.sh脚本并赋权限问题

    linux编写 sh脚本并赋权限问题 今日打包编译项目时 发现缺少一个git pull更新项目的脚本 所以在linux编写了一个gitpull sh脚本 能够实现更新项目的需求 1 首先vi gitpull sh或者使用vim编辑器 2 内
  • android 程序更新(没有sdcard)

    今天总结一下我们写的程序需要更新 默认用户已经安装上旧版本了 而用户更新时却没有sdcard的情况 如果有sdcard 那就不用废话了 先说一下软件更新的基本原理 从服务器下载一个程序的apk 然后启动安装 通常的情况下我们用到的都是在sd
  • nginx报错400

    当Nginx返回400错误时 通常是因为客户端发送的请求不符合服务器的要求或不完整 因此服务器无法正确处理请求 要解决这个问题 你可以采取以下步骤 检查请求的URL是否正确 确保请求的URL与服务器上的配置匹配 检查请求中的参数是否正确 确
  • 第二课 Flask路由、请求和会话

    Flask 第二课Flask路由 请求和会话 tags Flask 2019千锋教育 categories flask 视图 路由 Request对象 Response对象 Session Cookie Flask Session 文章目录
  • 关于this.getClass().getResource得URL为NULL的解决办法

    下面是我的文件结构 com graphPainting包下面存放的是java文件 depends是存放的依赖包 resources存放的是图片资源 输出之后 采用第1种写法一直显示get Resouces是NULL 还以为是文件路径有问题
  • 测试用例(微信发朋友圈/评论/点赞/搜索/购物车)

    一 微信朋友圈 功能 性能 界面 易用 安全 兼容 中断网 功能 是否能正常发布 是否能添加图片 是否能退出提示保存草稿 是否能添加表情 是否能设置仅自己可见 是否能设置发布的定位 是否能设置部分好友不可见 是否可以点赞评论 安全 信息是否
  • 编译并使用boost库(win7+boost1.63+vs2015+32位or 64位)

    博客 学院 下载 GitChat 论坛 问答 商城 VIP 活动 招聘 ITeye 码云 CSTO 写博客 发Chat 编译并使用boost库 win7 boost1 63 vs2015 32位or 64位 原创 2017年04月15日 2
  • PL/SQL Developer优化

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 工欲善其事 必先利其器 最近研究了一下各种编程工具的使用 发掘了不少新功能 能够大大提升我们日常的工作效率 下面是转载的一篇PLSQL使用技巧 个人感觉很有用 分享一下 1
  • Flutter自定义背景色渐变 按钮 组件

    这是笔者写的第一个 Flutter 自定义组件 在这里和大家分享一下 可能稍微有点粗糙 就当学习使用 首先我们先来看一下效果图 代码 import package flutter material dart void main gt run
  • DirectShow中常见的RGB/YUV格式

    小知识 RGB与YUV 摘自 DirectShow实务精选 作者 陆其明 计算机彩色显示器显示色彩的原理与彩色电视机一样 都是采用R Red G Green B Blue 相加混色的原理 通过发射出三种不同强度的电子束 使屏幕内侧覆盖的红
  • springboot中application.yml和bootstrap.yml文件的区别

    bootstrap yml是先头文件 在application yml之前读取 实际用途之一 在启动nacos管理的程序时 首先读取nacos上的配置文件 再读取本地的配置文件 application yml 需要将nacos上的配置文件和
  • linux红帽认证考试费,红帽rhce认证考试费用是多少?

    红帽rhce认证考试费用是多少 红帽认证rhce是Red Hat Certified Engineer的缩写 红帽认证考试费用大约为4200元人民币 不过在不同的考场会有一些价格差距 红帽认证是针对Linux平台操作的国际认证 是全球最权威
  • vlan划分_5种VLAN划分方式及其优缺点分析

    一 什么是VLAN VLAN Virtual Local Area Network 的中文名为 虚拟局域网 虚拟局域网 VLAN 是一组逻辑上的设备和用户 这些设备和用户并不受物理位置的限制 可以根据功能 部门及应用等因素将它们组织起来 相
  • STM32单片机串口中断接收,上电第一帧数据为0x00的问题解决

    以STM32G0单片机为例 全局变量定义 用于串口数据接收缓冲区 一个字节 uint8 t Rx Data 0 在初始化时 打开接收中断 HAL UART Receive IT huart1 uint8 t Rx Data 1 串口中断回调
  • Mac电脑怎么读写不了移动硬盘?解决苹果电脑不能读写移动硬盘问题

    相信大家在平时的生活和工作中肯定会有许多的备用资料放在移动硬盘里 当遇到要紧的事情需要在苹果电脑上打开移动硬盘时 却怎么也读写不出来 遇到这样的问题真的是非常的捉急 下面就让小编为大家解决一下吧 为什么我的苹果电脑不能读写移动硬盘 是不是一
  • 白盒测试方法-静态结构分析法

    程序的结构形式是白盒测试的主要依据 研究表明程序员38 的时间花费在理解软件系统上 因为代码以文本格式被写入多重文件中 这是很难阅读理解的 需要其它一些东西来帮助人们阅读理解 如各种图表等 而静态结构分析满足了这样的需求 在静态结构分析中
  • 商业公链之区块链技术使用的常见库(九)------Go语言http路由库"github.com/gorilla/mux"

    目录 介绍 安装 使用 常用方法介绍 1 初始化路由 2 路由注册 3 子路由的使用 4 定义路由别名 5 静态文件路由 7 生成已注册的URL 8 Walk方法 9 Middleware 中间件 10 开启监听端口 11 get请求处理