【go】总结笔记02

HandleFunc

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}

// pattern 是 URI 的规则,例如 /
// handler 是供调用的函数

ListenAndServe

func ListenAndServe(addr string, handler Handler) error {
	server := &Server{Addr: addr, Handler: handler}
	return server.ListenAndServe()
}

// addr 地址
// handler 通常为 nil,此种情况下会使用 DefaultServeMux

http.ServeMux

  • Go 标准库 net/http 包里自带的 http.ServeMux
  • 把收到的请求与一组预先定义的 URL 路径列表做对比,然后在匹配到路径的时候调用关联的处理器(Handler)
  • 无法直接从路由上区分 POST 或者 GET 等 HTTP 请求方法,只能手动判断
  • 不支持路由命名
  • 不支持 URI 路径参数
  • 徒增了代码的维护成本
package main

import (
	"fmt"
	"net/http"
	"strings"
)

func main() {
	router := http.NewServeMux()

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

	// 文章详情
	router.HandleFunc("/article/", func(w http.ResponseWriter, r *http.Request) {
		// 不支持 URI 路径参数,只能手动切割
		id := strings.SplitN(r.URL.Path, "/", 3)[2]
		fmt.Fprint(w, "文章id"+id)
	})
	// 列表 or 创建
	// 无法直接从路由上区分 POST 或者 GET 等 HTTP 请求方法,只能手动判断
	// 徒增了代码的维护成本
	router.HandleFunc("/articles", func(w http.ResponseWriter, r *http.Request) {
		switch r.Method {
		case "GET":
			fmt.Fprint(w, "访问文章列表")
		case "POST":
			fmt.Fprint(w, "创建新的文章")
		}
	})

	// 用以监听本地 3000 端口以提供服务
	http.ListenAndServe(":3000", router)
}

func defaultHandler(w http.ResponseWriter, r *http.Request) {
	// 设置header头
	if r.URL.Path == "/" {
		fmt.Fprint(w, "<h1>Hello, 欢迎来到 goblog!</h1>")
	} else {
		w.WriteHeader(http.StatusNotFound)
		fmt.Fprint(w, "<h1>请求页面未找到 :(</h1>"+
			"<p>如有疑惑,请联系我们。</p>")
	}
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	// 设置header头
	w.Header().Set("Content-Type ", "text/html;charset=utf8")
	fmt.Fprint(w, "<h1>this is go about</h1>")
}

HttpRouter

  • 目前来讲速度最快的路由器,且被知名框架 Gin 所采用
  • 路由功能相对简单,没有路由命名功能
  • 适合在要求高性能,且路由功能要求相对简单的项目中使用

gorilla/mux

  • 性能上虽然有所不及 HttpRouter,但是功能强大,全栈开发比较实用
  • 实现了 net/http 包的 http.Handler 接口,故兼容 http.ServeMux
  • 在 Gorilla Mux 中,如未指定请求方法,默认会匹配所有方法

安装

$ go get -u github.com/gorilla/mux

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

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

net/http:除了/其他都进入/about
gorilla/mux:只能匹配//about,其他都是404

package main

import (
	"fmt"
	"net/http"
	"github.com/gorilla/mux"
)

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

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

	// 文章模块
	// :区分正则,正则可省略
	// Methods 指定请求方法,不指定则全匹配
	// Name 指定路由命名
	router.HandleFunc("/article/{id:[0-9]+}", articleShowHandler).Methods("GET").Name("article.show")
	router.HandleFunc("/article", articleIndexHandler).Methods("GET").Name("article.index")
	router.HandleFunc("/article", articleStoreHandler).Methods("POST").Name("article.store")

	// 404
	router.NotFoundHandler = http.HandlerFunc(notFoundHandler)

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

	// 用以监听本地 3000 端口以提供服务
	http.ListenAndServe(":3000", router)
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf8")
	fmt.Fprint(w, "<h1>this is home</h1>")
}

func aboutHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf8")
	fmt.Fprint(w, "<h1>this is about</h1>")
}

func notFoundHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf8")
	fmt.Fprint(w, "<h1>请求页面未找到</h1>")
}

func articleShowHandler(w http.ResponseWriter, r *http.Request) {
	// 会将 URL 路径参数解析为键值对应的 Map
	vars := mux.Vars(r)
	id := vars["id"]
	fmt.Fprint(w, "文章详情:"+id)
}

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

func articleStoreHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "文章新增")
}

理解

  • 并不是标准库里的就是最好了,不能被固有思想限制,很多第三方的库也很优秀,格局打开

题外话:新手入门,多有不解,理解有偏差请不吝指教

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值