Code前端首页关于Code前端联系我们

Golang语言如何使用net/http标准库开发http应用程序?

terry 2年前 (2023-09-24) 阅读数 58 #后端开发

01

简介

在golang语言中,可以使用net/http来实现http服务器。可以输入指定的参数、地址和处理器(操作员)。如果处理器参数为 nil,则默认使用 DefaultServeMux

您还可以使用net/http标准库来实现http客户端。 HTTP(或 https)可以通过调用 GetHeadPostPost 来发送。 功能。寻找。请注意,客户端完成请求后,必须关闭响应正文。

02

Server

使用net/http标准库来实现http服务器。一般有两种方式,即使用处理器和处理器功能。

处理器管理器

其中处理器模式包括单处理器和多处理器。

单处理器,示例代码:

func main () {
 hello := Hello{name: "frank"}
 httpServer := http.Server{Addr: ":8080", Handler: &hello}
 httpServer.ListenAndServe()
}

type Hello struct {
 name string
}

func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello " + h.name)
}

阅读上面的代码,我们发现定义了一个结构体类型变量,并创建了一个HandlerServeHTTP(ResponseWriter, *Request)

func main () {
 http.HandleFunc("/client", client)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func client(w http.ResponseWriter, r *http.Request) {
 resp, err := http.Get("http://127.0.0.1:8080/hello")
 if err != nil {
  log.Fatal(err)
 }
 data, err := io.ReadAll(resp.Body)
 if err != nil {
  log.Fatal(err)
 }
 defer resp.Body.Close()
 fmt.Fprintln(w, string(data))
}

04

并赋值给http.Server 用于处理程序字段。

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

阅读源码,我们可以看到Handler是一个接口,其中包含ServeHTTP(ResponseWriter, *Request)方法。

使用处理器传输参数很方便。但无法匹配多条路由,因此如果需要匹配多条路由,可以使用多个处理器。

多个处理器,示例代码:

func main () {
 httpServer := http.Server{
  Addr:              ":8080",
 }
 http.Handle("/hello", Hello{})
 http.Handle("/world", World{})
 httpServer.ListenAndServe()
}
type Hello struct {}
type World struct {}
func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}
func (w1 World) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "world")
}

阅读上面的代码,可以看到我们创建了多个处理器,然后调用http.Handle函数将处理器注册到♓ultra。 ,多路复用器将路由请求转发给路由的ServerHTTP方法进行处理。

通过使用多个处理器,一个处理器可以匹配一条路由。通过创建多个处理器可以匹配多条路由。

处理器功能

处理器模式,1条路由对应1个处理器(操作员)。如果我们有更多的路由,我们就必须创建更多的处理器,这使用起来有点麻烦。因此,net/http标准库提供了实现参数路由的函数HandleFunc和处理函数♶erult。

handler func 还实现了 Handler 结构的 ServeHTTP(ResponseWriter, *Request) 方法。

处理函数(handler func),示例代码:

func main () {
 http.HandleFunc("/hello", hello)
 http.HandleFunc("/world", world)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func hello(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}
func world(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "world")
}

阅读上面的代码,我们发现使用处理器函数相对于处理器的使用方式减少了代码量。然而,传递参数变得很优雅。在使用的时候,我们可以根据场景选择最好的。

精明的读者可能会注意到,上面的示例使用了DefaultServeMux。为什么不使用 http.NewServeMux 创建一个新的多路复用器?

因为net/http标准库默认创建DefaultServeMux。函数 http.Handlehttp.HandleFunc 将处理程序注册到 L,在DefaultServeMux AndServe 如果未接收handler参数,默认为DefaultServeMux

源代码为:

func NewServeMux() *ServeMux { return new(ServeMux) }

var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux

func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }

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

我们还可以创建一个新的多路复用器来处理路由请求,包括处理器模式和处理器功能模式。

处理器模式,示例代码:

func main () {
 serveMux := http.NewServeMux()
 hello := Hello{}
 serveMux.Handle("/hello", hello)
 http.ListenAndServe(":8080", serveMux)
}

type Hello struct {}

func (h Hello) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}

阅读上面的代码,使用创建的多路复用器,调用多路复用器的Handle方法注册处理器(Handler)。

Handler函数模式,示例代码:

func main () {
 serveMux := http.NewServeMux()
 hello := http.HandlerFunc(Hello)
 serveMux.Handle("/hello", hello)
 http.ListenAndServe(":8080", serveMux)
}

func Hello (w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, "hello")
}

阅读上面的代码,使用函数http.HandlerFunc避免函数类型参数进入HandlerFunc。

03

Client

使用net/http标准库来实现http客户端。HTTP(或 https)可以通过调用 GetHeadPostPost 来发送。 功能。寻找。请注意,客户端完成请求后,必须关闭响应正文。

示例代码:

func main () {
 http.HandleFunc("/client", client)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func client(w http.ResponseWriter, r *http.Request) {
 resp, err := http.Get("http://127.0.0.1:8080/hello")
 if err != nil {
  log.Fatal(err)
 }
 data, err := io.ReadAll(resp.Body)
 if err != nil {
  log.Fatal(err)
 }
 defer resp.Body.Close()
 fmt.Fprintln(w, string(data))
}

04

Request Param

在接收请求参数方面,http.Request还提供了一定的函数和方法。由于篇幅限制,本文仅提供一个示例,并非用于此目的。进一步介绍。

func main () {
 http.HandleFunc("/param1", param1)
 http.HandleFunc("/param2", param2)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func param1(w http.ResponseWriter, r *http.Request) {
 r.ParseForm()
 fmt.Fprintln(w, r.Form["user"][0])
}
func param2(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintln(w, r.FormValue("user"), r.FormValue("age"))
}

阅读上面的代码,我们定义了两个接收请求参数的函数,请求参数分别是 r.ParseForm

r.FormValue 其中♓ r.ParseFome 方法将参数解析为r.Form格式,r.FormValue方法直接返回给定字符串类型参数key的第一个值。更多使用方法请阅读官方文档。

05

响应结果

至于响应的结果,http.ResponseWriter接口提供了三种方法:

type ResponseWriter interface {
 Header() Header
 Write([]byte) (int, error)
 WriteHeader(statusCode int)
}

这里我不只是举一个例子。更多使用方法请阅读官方文档。

func main () {
 http.HandleFunc("/json", jsonRes)
 err := http.ListenAndServe(":8080", nil)
 if err != nil {
  log.Fatal(err)
 }
}
func jsonRes(w http.ResponseWriter, r *http.Request) {
 w.Header().Set("Content-Type", "application/json")
 ageStr := r.FormValue("age")
 ageInt, err := strconv.Atoi(ageStr)
 if err != nil {
  log.Fatal(err)
 }
 age := uint8(ageInt)
 username := r.FormValue("user")
 jsonData, err := json.Marshal(struct {
  Username string
  Age uint8
 }{username, age})
 if err != nil {
  log.Fatal(err)
 }
 fmt.Fprintln(w, string(jsonData))
}

06

总结

在本文中,我们主要介绍使用net/http标准库来实现http服务器和http客户端。并简要列出了请求参数和响应结果的使用示例。 cookie的操作在之前的文章公众号中已有介绍,本文不再重复。

最重要的方面是处理器和多路复用器,包括处理器和处理器功能、新的多路复用器和默认的多路复用器。此外,net/http标准库还包含几个可用作处理程序的内置函数,例如NotFoundHandler和❙❀和

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门