Part 1: Hello World
“Hello, World”程序指的是只在计算机屏幕上输出“Hello, World!”(意为“世界,你好!”)这行字符串的计算机程序。一般来说,这是每一种计算机编程语言中最基本、最简单的程序,亦通常是初学者所编写的第一个程序。它还可以用来确定该语言的编译器、程序开发环境,以及运行环境是否已经安装妥当。
在Go’s net/http 文档中我们可以看到一个运行第一个 Go web 应用程序的示例:
1 2 3 4 5 6 7 |
http.Handle("/foo", fooHandler) http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) }) log.Fatal(http.ListenAndServe(":8080", nil)) |
这种创建web server的方式,我们称他为“functional”式或者“package level”式的,我们使用了包级别的函数访问隐式的的全局 http 服务和一个隐式的的全局logger实例,我们只用内联函数作为我们handler。
接下来我们在main package 中让我们的上面的代码能够demo能够运行起来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package main import ( "log" "net/http" ) func main() { http.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) { log.Println("request to foo") }) http.ListenAndServe(":8080", nil) } |
当我们运行上面的代码的时候,我们在浏览器输入:http://127.0.0.1:8080/foo的时候我们就会看到终端活输出:
1 |
request to foo |
或者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package main import ( "io" "net/http" "log" ) // hello world, the web server func HelloServer(w http.ResponseWriter, req *http.Request) { io.WriteString(w, "hello, world!\n") } func main() { http.HandleFunc("/hello", HelloServer) log.Fatal(http.ListenAndServe(":12345", nil)) } |
当我们运行上面的代码的时候,我们在浏览器输入:http://127.0.0.1:8080/hello的时候我们会在浏览器看到打印的:hello,world!
https实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import ( "log" "net/http" ) func handler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Write([]byte("This is an example server.\n")) } func main() { http.HandleFunc("/", handler) log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/") err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil) log.Fatal(err) } |
这里是https实现和上面的ListenAndServe 不同的是我们需要配置https的证书。
Part 2: 自定义全局路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package main import ( "log" "net/http" "os" ) var ( logger *log.Logger ) func main() { logger = log.New(os.Stdout, "web ", log.LstdFlags) server := &http.Server{ Addr: ":8080", Handler: routes(), } server.ListenAndServe() } func routes() *http.ServeMux { r := http.NewServeMux() r.HandleFunc("/foo", foo) return r } func foo(w http.ResponseWriter, r *http.Request) { logger.Println("request to foo") } |
Part 3: 面向对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package main import ( "log" "net/http" "os" ) func main() { http.ListenAndServe(":8080", New()) } func New() http.Handler { mux := http.NewServeMux() log := log.New(os.Stdout, "web ", log.LstdFlags) app := &app{mux, log} mux.HandleFunc("/foo", app.foo) return app } type app struct { mux *http.ServeMux log *log.Logger } func (a *app) ServeHTTP(w http.ResponseWriter, r *http.Request) { a.mux.ServeHTTP(w, r) } func (a *app) foo(w http.ResponseWriter, r *http.Request) { a.log.Println("request to foo") } |
当我们的应用程序做到真正的面向对象的时候,你会发现封装、依赖和测试将会变得简单。
有疑问加站长微信联系(非本文作者)