zoukankan      html  css  js  c++  java
  • Go Web编程 第三章--接收请求

    net/http标准库

    net/http标准库通常包括两个部分,客户端和服务器,我们可以通过ListenAndServe创建一个简陋的服务器

    package main
    
    import (
        "net/http"
    )
    
    func main() {
        http.ListenAndServe("", nil)
    }
    

    这会使用默认的80端口进行网络连接,并且使用默认的多路复用器DefaultServeMux,我们也可以通过Server结构进行更详细的配置

    func main() {
        server := http.Server {
            Addr: "127.0.0.1:80",
            Handler: nil,
        }
        server.ListenAndServe()
    }
    

    处理器和处理函数

    处理器

    前面的代码会返回404响应,因为我们还没有为请求编写相应的处理器。一个处理器就是一个拥有ServeHTTPf方法的接口

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

    我们通过实现这个接口来编写处理器

    type MyHandler struct{}
    
    func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, world")
    }
    
    func main() {
        handler := MyHandler{}
        server := http.Server {
            Addr: "127.0.0.1:80",
            Handler: &handler,
        }
        server.ListenAndServe()
    }
    

    我们可以设置多个处理器

    type HelloHandler struct{}
    
    func (hello *HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "hello!")
    }
    
    type WorldHandler struct{}
    
    func (world *WorldHandler) ServeHTTP(w http.ResponseWriter, r *http.Reuest) {
        fmt.Fprintf(w, "world!")
    }
    
    func main() {
        hello := HelloHandler{}
        world := WorldHandler{}
    
        server := http.Server {
            Addr: "127.0.0.1:80",
        }
        http.Handle("/hello", &hello)
        http.Handle("/world", &world)
    
        server.ListenAndServe()
    }
    

    我们看一下Handle函数再源码中的定义

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

    实际上是在调用DefaultServeMux的某个方法,前面我们已经提到过了DefaultServeMux是个默认多路复用器,实际上它也是个Handler处理器,因为他是ServeMux结构的一个实例,而ServeMux也实现了Handler接口的ServeHTTP方法。这样就可以对不同的请求做出不同的响应。

    处理器函数

    处理器函数是与处理器拥有同样行为的函数,它们与ServeHTTP拥有同样的函数签名。

    func hello (w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello!")
    }
    
    func main() {
        server := http.Server {
            Addr: "127.0.0.1:8080",
        }
        http.HandleFunc("/hello", hello)
    
        server.ListenAndServe()
    }
    

    HandleFunc是Go语言拥有的一种函数类型,它可以把一个带有正确签名的f转换为带有方法f的handler。
    来看看HandleFunc的源码

    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        DefaultServeMux.HandleFunc(pattern, handler)
    }
    
    func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
        if handler == nil {
            panic("http: nil handler")
        }
        mux.Handle(pattern, HandlerFunc(handler))
    }
    

    Handle函数是不是似曾相识!

    串联多个处理器和处理器函数

    func hello(w *http.ResponseWriter, r *Request) {
        fmt.Fprintf(w, "Hello!")
    }
    
    func log(h http.Handler) http.HandlerFunc {
        return func(w http.ResponseWriter, r *http.Request) {
            fmt.Println("Log!")
            h(w, r)
        }
    }
    
    func main() {
        server := http.Server {
            Addr: "127.0.0.1:8080",
        }
        http.HandleFunc("/hello", log(hello))
        server.ListenAndServe()
    }
    

    其中HandlerFunc是实现了Handler接口的函数类型,源码定义:

    type HandlerFunc func(ResponseWriter, *Request)
    
    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
        f(w, r)
    }
    

    ServeMux

    ServeMux是一个HTTP请求多路复用器,负责接收HTTP请求并根据请求中的URL将请求重定向到正确的处理器。ServeMux包含一个映射,这个映射会将URL映射至相应的处理器。值得一提的是,ServeMux无法使用变量实现URL模式匹配,因此必要时我们完全可以用其它自建的多路复用器来代替ServeMux,如HttpRouter等高效轻量的第三方复用器

  • 相关阅读:
    Gradle构建模块化项目
    线程池的理解与应用
    Redis理解
    kafka监听出现的问题,解决和剖析
    shiro利用过期时间,解决用户冻结踢出问题
    信息系统的运行与维护包含的主要内容
    软件维护的内容是什么
    执行顺序
    Chrome/Edge 91版本SameSite by default cookies被移除后的解决方案
    公从号编程
  • 原文地址:https://www.cnblogs.com/authetic/p/10199445.html
Copyright © 2011-2022 走看看