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>
*/









