Go语言中http和mysql的实现代码

2020-01-28 13:43:47刘景俊

panic 处理

如果处理函数里有panic,会导致整个程序崩溃,所以要 defer revoer() 来处理 panic。在处理函数开头defer一个匿名函数:


func FormServer(w http.ResponseWriter, request *http.Request) {
 // 增加一个defer来处理panic
 defer func() {
  if x := recover(); x != nil {
   log.Println(request.RemoteAddr, "捕获到异常:", x)
  }
 }()
 // 原本的处理函数的内容
 w.Header().Set("content-Type", "text/html")
 switch request.Method {
 case "GET":
  io.WriteString(w, form)
 case "POST":
  request.ParseForm()
  io.WriteString(w, request.FormValue("in")) // 一般去一个值,就用这个方法
 }
 // 搞个panic出来
 zero := 0
 tmp := 1 / zero
 io.WriteString(w, string(tmp))
}

优化统一处理

按照上面的做法,要在每个处理函数的开头都加上panic的处理。由于每个处理函数的panic处理方法都一样,所以可以写一个自定义的处理函数:


// 自定义的panic处理的函数
func logPanics(handle http.HandlerFunc) http.HandlerFunc {
 return func(writer http.ResponseWriter, request *http.Request) {
  defer func() {
   if x := recover(); x != nil {
    log.Println(request.RemoteAddr, "捕获到异常:", x)
   }
  }()
  // 上面先处理panic,再接着下面调用业务逻辑
  handle(writer, request)
 }
}

func main() {
 // http.HandleFunc("/form", FormServer) // 修改调用处理函数的方法
 http.HandleFunc("/form", logPanics(FormServer)) // 把处理函数传给自己写的封装了panic处理的函数里
 if err := http.ListenAndServe(":8000", nil); err != nil {
  fmt.Println("监听端口ERROR:", err)
 }
}

原本直接调用处理函数。现在调用自定义的函数,把处理函数传进去。在自定义的函数里先加载defer,然后再调用执行原本的处理函数。逻辑很简单,就是把处理函数作为参数传给自定义的函数,在自定义的函数里再调用处理函数。在自定义的函数里写上defer,这样就相当于所有的处理函数都有defer了。

模板

使用模板需要用到 "text/template" 包。然后调用模板的t.Execute()方法输出。

替换

先准备一个简单的模板:


<p>Hello {{.Name}}</p>
<p>Age: {{.Age}}</p>

然后在Go里使用模板:


package main

import (
 "fmt"
 "os"
 "text/template"
)

type Person struct {
 Name string
 Age int
}

func main() {
 t, err := template.ParseFiles("index.html")
 if err != nil {
  fmt.Println("模板解析异常:", err)
  return
 }
 p := Person{"Bob", 32}
 if err := t.Execute(os.Stdout, p); err != nil {
  fmt.Println("模板加载数据异常:", err)
 }
}

/* 执行结果
PS H:Gosrcgo_devday10httpuse_template> go run main.go
<p>Hello Bob</p>
<p>Age: 32</p>
PS H:Gosrcgo_devday10httpuse_template>
*/