[Go]接收請求

小黑
發佈於後端
2024/01/01閱讀時間約 10 分鐘

ServeMux

ServeMux是一個包含映射的結構,映射會將URL映射到對應的伺服器。


DefaultServeMux

DefaultServeMux是net/HTTP中預設的多工器,是ServeMux的實例。多工器要根據URL的請求導向到不同的伺服器。DefaultServeMux是一個全域變數,也就是說專案裡的任何地方都能對它做修改,因此就可能會發生處理器衝突。所以比較建議自訂多工器。


自訂多工器

package main

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

func hi(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi")
}

func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", hi)

server := &http.Server{
Addr: ":8081",
Handler: mux,
}

if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}


HttpRouter

HttpRouter是一個高效能、可擴充的第三方套件。他尼補了net/HTTP預設路由不足的問題。

安裝

go get -u​ github.com/julienschmidt/httprouter


GET

package main

import (
"github.com/julienschmidt/httprouter"
"net/http"
)

func main() {
router := httprouter.New()
router.GET("/default", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Write([]byte("default get"))
})

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


POST

package main

import (
"github.com/julienschmidt/httprouter"
"net/http"
)

func main() {
router := httprouter.New()
router.POST("/default", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Write([]byte("default post"))
})

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


匹配方式

  • 精確匹配:/user/:name
package main

import (
"github.com/julienschmidt/httprouter"
"net/http"
)

func main() {
router := httprouter.New()

//精确匹配
router.GET("/user/name", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
w.Write([]byte("user name:" + p.ByName("name")))
})

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


  • 所有樣式:/user/*name
package main

import (
"github.com/julienschmidt/httprouter"
"net/http"
)

func main() {
router := httprouter.New()
//所有樣式
router.GET("/user/*name", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
w.Write([]byte("user name:" + p.ByName("name")))
})
http.ListenAndServe(":8083", router)
}


處理二級域名

package main

import (
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)

type HostMap map[string]http.Handler

func (hs HostMap) ServeHTTP(w http.ResponseWriter, r *http.Request) {
//根據網域取得對應的Handler路由,然後呼叫處理(分發機制)
if handler := hs[r.Host]; handler != nil {
handler.ServeHTTP(w, r)
} else {
http.Error(w, "Forbidden", 403)
}
}

func main() {
userRouter := httprouter.New()
userRouter.GET("/", func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
w.Write([]byte("sub1"))
})

dataRouter := httprouter.New()
dataRouter.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Write([]byte("sub2"))
})

//分別用於處理不同的二級域名
hs := make(HostMap)
hs["sub1.localhost:8888"] = userRouter
hs["sub2.localhost:8888"] = dataRouter

log.Fatal(http.ListenAndServe(":8888", hs))
}


靜態檔案服務

package main

import (
"log"
"net/http"
"github.com/julienschmidt/httprouter"
)

func main() {
router := httprouter.New()

router.ServeFiles("/static/*filepath", http.Dir("./files"))
log.Fatal(http.ListenAndServe(":8086", router))
}

ServeFiles()第一個參數路徑必須是「/static/*filepath」;第二個參數為檔案目錄。


處理器

package main

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

type WelcomeHandler struct {
Language string
}

func (h WelcomeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%s", h.Language)
}

func main() {
mux := http.NewServeMux()
mux.Handle("/cn", WelcomeHandler{Language: "Go!"})

server := &http.Server {
Addr: ":8082",
Handler: mux,
}

if err := server.ListenAndServe(); err != nil {
log.Fatal(err)
}
}


處理器函數

package main

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

func hi(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Go go!")
}

func main() {
http.HandleFunc("/", hi)
if err := http.ListenAndServe(":8081", nil); err != nil {
log.Fatal(err)
}
}




7會員
78內容數
嗨,我是一名程式設計師,會在這分享開發與學習紀錄。
留言0
查看全部
發表第一個留言支持創作者!