Golang【Web 入门】 08 集成 Gorilla Mux

news2024/11/16 23:57:55

阅读目录

  • 集成 Gorilla Mux
    • 为什么不选择 HttpRouter?
    • 安装 gorilla/mux
    • 使用 gorilla/mux
    • 迁移到 Gorilla Mux
      • 1. 新增 homeHandler
      • 2. 指定 Methods () 来区分请求方法
      • 3. 请求路径参数和正则匹配
      • 4. 命名路由与链接生成

集成 Gorilla Mux

我们将选用 gorilla/mux 来作为 goblog 的路由器。

https://github.com/gorilla/mux

为什么不选择 HttpRouter?

HttpRouter
https://github.com/julienschmidt/httprouter

Gin
https://github.com/gin-gonic/gin

HttpRouter 是目前来讲速度最快的路由器,且被知名框架 Gin 所采用。

不选择 HttpRouter 的原因是其功能略显单一,没有路由命名功能,不符合我们的要求。

HttpRouter 和 Gin 比较适合在要求高性能,且路由功能要求相对简单的项目中,如 API 或微服务。在全栈的 Web 开发中,gorilla/mux 在性能上虽然有所不及,但是功能强大,比较实用。

安装 gorilla/mux

这是我们第一次安装第三方依赖,goblog 项目将使用官方推荐的 Go Module 来管理第三方依赖。

Go Modules 相关知识下一节再来讲。本节专注于安装和使用 gorilla/mux。

下面使用 go get 命令安装 gorilla/mux :

go get -u github.com/gorilla/mux

安装成功后使用 git status 可以看到有两个文件变跟:

输出:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

提示: 下一节,我们再来讲解这两个文件的作用。

使用 gorilla/mux

gorilla/mux 因实现了 net/http 包的 http.Handler 接口,故兼容 http.ServeMux ,也就是说,我们可以直接修改一行代码,即可将 gorilla/mux 集成到我们的项目中:

main.go

func main() {
    router := mux.NewRouter()
}

注意: 修改以上代码后保存,因为安装了 Go for Visual Studio Code 插件,VSCode 会自动在文件顶部的 import 导入 mux 库,我们无需手动添加。

依次以下链接:

localhost:3000/
localhost:3000/about
localhost:3000/articles
localhost:3000/no-exists
localhost:3000/articles/2
localhost:3000/articles/

可以发现:

123 可以正常访问。
4 无法访问到自定义的 404 页面
5 文章详情页无法访问
6 可以访问到文章页面,但是 ID 为空

这是因为 gorilla/mux 的路由解析采用的是 精准匹配 规则,而 net/http 包使用的是 长度优先匹配 规则。

精准匹配 指路由只会匹配准确指定的规则,这个比较好理解,也是较常见的匹配方式。

长度优先匹配 一般用在静态路由上(不支持动态元素如正则和 URL 路径参数),优先匹配字符数较多的规则。

以我们的 goblog 为例:

router.HandleFunc("/", defaultHandler)
router.HandleFunc("/about", aboutHandler)

使用 长度优先匹配 规则的 http.ServeMux 会把除了 /about 这个匹配的以外的所有 URI 都使用 defaultHandler 来处理。

而使用 精准匹配 的 gorilla/mux 会把以上两个规则精准匹配到两个链接,/ 为首页,/about 为关于,除此之外都是 404 未找到。

知道这个规则后,配合上面几个测试链接的返回结果,会更好理解。

一般 长度优先匹配 规则用在静态内容处理上比较合适,动态内容,例如我们的 goblog 这种动态网站,使用 精准匹配 会比较方便。

迁移到 Gorilla Mux

基于以上规则,接下来改进代码:

main.go

package main

import (
	"fmt"
	"net/http"

	"github.com/gorilla/mux"
)

func homeHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprint(w, "<h1>Hello, 欢迎来到 goblog!</h1>")
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	fmt.Fprint(w, "此博客是用以记录编程笔记,如您有反馈或建议,请联系 "+
		"<a href=\"mailto:1157818690@qq.com\">1157818690@qq.com</a>")
}

func notFoundHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.WriteHeader(http.StatusNotFound)
	fmt.Fprint(w, "<h1>请求页面未找到 :(</h1><p>如有疑惑,请联系我们。</p>")
}

func articlesShowHandler(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]
	fmt.Fprint(w, "文章 ID:"+id)
}

func articlesIndexHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "访问文章列表")
}

func articlesStoreHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "创建新的文章")
}

func main() {
	router := mux.NewRouter()

	router.HandleFunc("/", homeHandler).Methods("GET").Name("home")
	router.HandleFunc("/about", aboutHandler).Methods("GET").Name("about")

	router.HandleFunc("/articles/{id:[0-9]+}", articlesShowHandler).Methods("GET").Name("articles.show")
	router.HandleFunc("/articles", articlesIndexHandler).Methods("GET").Name("articles.index")
	router.HandleFunc("/articles", articlesStoreHandler).Methods("POST").Name("articles.store")

	// 自定义 404 页面
	router.NotFoundHandler = http.HandlerFunc(notFoundHandler)

	// 通过命名路由获取 URL 示例
	homeURL, _ := router.Get("home").URL()
	fmt.Println("homeURL: ", homeURL)
	articleURL, _ := router.Get("articles.show").URL("id", "23")
	fmt.Println("articleURL: ", articleURL)

	http.ListenAndServe(":3000", router)
}

接下来我们一步步分解代码。

1. 新增 homeHandler

首先,因为使用的是精确匹配,我们将 defaultHandler 变更 homeHandler 且将处理 404 的代码移除。

2. 指定 Methods () 来区分请求方法

看下这两个路由:

router.HandleFunc("/articles", articlesIndexHandler).Methods("GET").Name("articles.index")
router.HandleFunc("/articles", articlesStoreHandler).Methods("POST").Name("articles.store")

命令行:

E:\golang\src>curl http://127.0.0.1:3000/articles
访问文章列表
E:\golang\src>curl -X POST http://127.0.0.1:3000/articles
创建新的文章
E:\golang\src>

解析正确。

注意: 在 Gorilla Mux 中,如未指定请求方法,默认会匹配所有方法。

3. 请求路径参数和正则匹配

我们的文章详情页面的匹配:

router.HandleFunc("/articles/{id:[0-9]+}", articlesShowHandler).Methods("GET").Name("articles.show")

注意 ID 路径的设置:

{id:[0-9]+}

有以下规则:

  • 使用 {name} 花括号来设置路径参数。
  • 在有正则匹配的情况下,使用 : 区分。第一部分是名称,第二部分是正则表达式。
[0-9]+

限定了 一个或者多个的数字。如果你访问非数字的 ID ,如 localhost:3000/articles/string 即会看到 404 页面。

再看下在 Handler 里面我们如何获取到这个参数:

func articlesShowHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    id := vars["id"]
    fmt.Fprint(w, "文章 ID:"+id)
}

Mux 提供的方法 mux.Vars® 会将 URL 路径参数解析为键值对应的 Map,使用以下方法即可读取:

vars["id"]

4. 命名路由与链接生成

router.HandleFunc("/", homeHandler).Methods("GET").Name("home")
router.HandleFunc("/articles/{id:[0-9]+}", articlesShowHandler).Methods("GET").Name("articles.show")

Name() 方法用来给路由命名,传参是路由的名称,接下来我们就可以靠这个名称来获取到 URI:

homeURL, _ := router.Get("home").URL()
fmt.Println("homeURL: ", homeURL)
articleURL, _ := router.Get("articles.show").URL("id", "1")
fmt.Println("articleURL: ", articleURL)

命令行切到我们的 air 窗口,即可看到 fmt.Println 打印出来的内容:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/55611.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS页面布局(超详解)

目录 1 CSS页面布局概述 1.1 概述 1.2 网页栏目划分 1.3 元素类型转化 1.3.1 块元素 1.3.2 行内元素 1.3.2 块元素和行内元素的转换 1.4 定位 1.4.1 静态定位 1.4.2 相对定位 1.4.3 绝对定位 1.4.4 固定定位 1.4.5 定位元索的层叠次序 1.5 浮动 1.5.1 概述 1.5…

JAVA中如何精确取到时间

文章目录0 写在前面1 使用方法2 举例3 写在最后0 写在前面 做业务的时候&#xff0c;总要统计数据&#xff0c;几月份到几月份的全部数据。这个时候就要找到起始月份的具体时间和终止月份的具体时间。 此时我们用原始的Date类去处理就比较麻烦&#xff0c;可以自己写一个工具类…

Web3中文|什么是以太坊虚拟机(EVM),它是如何工作的?

来源 | cointelegraph 编译 | DaliiNFTnews.com 以太坊已成为仅次于比特币的第二重要区块链。以太坊能发展得这么好&#xff0c;它的原生Solidity编程语言和以太坊虚拟机&#xff08;EVM&#xff09;发挥了重要的作用。 以太坊区块链凭借自身拥有的灵活性、大量可用的开发工…

MySQL高级SQL语句

一.准备 mysql -uroot -p123123create database train_ticket; #创建库use train_ticket; create table REGION(region varchar(10),site varchar(20)); create table FARE(site varchar(20),money int(10),date varchar(15)); #创建表desc REGION; desc FARE; #查看表结构ins…

[附源码]计算机毕业设计云南美食管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

浅析linux内核网络协议栈--linux bridge(二)

6. 网桥数据转发 6.1 网桥数据包入口 网桥是一种2层网络互连设备&#xff0c;而不是一种网络协议。它在协议结构上并没有占有一席之地&#xff0c;因此不能通过向协议栈注册协议的方式来申请网桥数据包的处理。相 反&#xff0c;网桥接口&#xff08;如上述的eth1&#xff09…

mysql—MHA原理与实现

官方介绍&#xff1a;https://code.google.com/p/mysql-master-ha/ MySQL复制集群中的master故障时&#xff0c;MHA按如下步骤进行故障转移&#xff1a; 从上图可总结MHA工作步骤为&#xff1a; -从宕机崩溃的master保存二进制日志事件(binlogevents)。 -识别含有最新更新的s…

macOS Electron 环境安装时的错误 Cannot find module ‘macos-alias‘ 解决

macOS Electron 环境安装时的错误 Cannot find module ‘macos-alias’ 解决 一、问题描述 在想 make 并发布软件版本的时候&#xff0c;现出这个错误&#xff1a; ❯ Making distributables✖ Making a dmg distributable for darwin/arm64› Cannot find module macos-ali…

SSM处理过程

SSM框架是spring MVC &#xff0c;spring和mybatis框架的整合&#xff0c;是标准的MVC模式&#xff0c;将整个系统划分为表现层&#xff0c;controller层&#xff0c;service层&#xff0c;DAO层四层 使用spring MVC负责请求的转发和视图管理 spring实现业务对象管理&#xf…

DSP篇--C6678功能调试系列之TIMER、UART调试

目录 1、TIMER计时器调试 2、UART串口调试 2.1 核传输 2.2 EDMA传输 1、TIMER计时器调试 The TMS320C6678 device has sixteen 64-bit timers in total. Timer0 through Timer7 are dedicated to each of the eight CorePacs as a watchdog timer and can also be used as g…

黄东旭:开发者的“技术无感化”时代,从 Serverless HTAP 数据库开始 | PingCAP DevCon 2022

12 月 1 日&#xff0c;以"去发现&#xff0c;去挑战"为主题的 PingCAP DevCon 2022 主论坛在线上成功举办&#xff0c;为数万观众带来一场技术盛宴。PingCAP 联合创始人兼 CTO 黄东旭&#xff0c;在大会上分享了“The Future of Database”的主题演讲&#xff0c;分…

Unity记录几个5.x升级到2018问题

XLua的 ILType Emit等C#框架问题 本来是Unity5.x&#xff0c;貌似是最旧的代码 。Net 2.0 无奈升级用了Unity2018之后&#xff0c;只支持4.x&#xff0c; 在PlayerSetting面板&#xff0c;改成.Net3.5&#xff0c;居然阔以了 (Unity2018.7 - 支持的最低&#xff0c;.Net 3.x…

使用 Learner Lab - 学生

使用 Learner Lab - 学生 AWS Academy Learner Lab 是提供一个帐号让学生可以自行使用 AWS 的服务&#xff0c;让学生可以在 100 USD的金额下&#xff0c;自行练习所要使用的 AWS 服务&#xff0c;AWS Academy 学习平台建立 Learner Lab &#xff0d; 教师 这篇文章介绍老师如…

【JVM】 类加载器 ClassLoader

一、JVM 类加载器 JVM 具有 4 种类加载器&#xff1a; 引导类加载器 &#xff1a; 负责加载支持 JVM 运行的位于 JRE 的 lib 目录下的核心类库&#xff0c;比如 rt.jar 、charsets.jar 等等扩展类加载器&#xff1a;负责加载支撑 JVM 运行的位于 JRE 的 lib 目录下的 ext 扩展…

java计算机毕业设计ssm宁夏源沣医药线上销售平台thd3v(附源码、数据库)

java计算机毕业设计ssm宁夏源沣医药线上销售平台thd3v&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&a…

戳进来,带你走近飞凌嵌入式旗舰级AIoT芯RK3588开发板

飞凌嵌入式OK3588-C开发板现已正式发售&#xff01;真8K、强大算力、出色的多媒体性能、丰富的用户资料......多重优势为您带来更优质的体验&#xff01; OK3588-C开发板基于Rockchip旗舰级AIoT处理器RK3588设计开发&#xff0c;先进的8nm制程工艺、Big.Little大小核架构以及L3…

[附源码]计算机毕业设计springboot学分制环境下本科生学业预警帮扶系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

基于PHP+MySQL班级信息发布和管理系统的设计与实现

一直以来我国领导人提倡以人为本的治国方案&#xff0c;而大学是未来人才的培养基地&#xff0c;如何能够更好的对学生信息进行管理&#xff0c;是很多高校一直在研究的一个问题&#xff0c;只有更加科学的对学生信息进行管理&#xff0c;才能够更加积极的培养国家的栋梁之才。…

VIAVI唯亚威SmartPocket V2 OLS-35V2/-36V2 光学光功率计

OLS-3xV2 是一系列小巧、坚固耐用的光学光源 (OLS)&#xff0c;用于快速、轻松、方便地进行现场插入损耗测量和连续性检查。SmartPocket V2 OLS 是与 OLP-3xV2 光功率计相辅相成的理想工具&#xff0c;可在单模 (SM) 和多模 (MM) 光纤网络中实现插入损耗和连续性测试。坚固小巧…