4.08 Go Web程序(7)|Go主题月

413 阅读2分钟

  上一章节中,我们将对应的编辑以及查看的页面页面操作写完成了,接下来我们就是对其进行完善。

代码编写

在我们的程序中有几个地方错误被忽略了。这是一种不好的实践,尤其是因为当错误发生时,程序将产生意想不到的行为。更好的解决方案是处理错误并向用户返回错误消息。这样,如果出现错误,服务器将按照我们希望的方式运行,并通知用户。

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
    t, err := template.ParseFiles(tmpl + ".html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    err = t.Execute(w, p)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

http.Error函数发送指定的HTTP响应代码(在本例中为“内部服务器错误”)和错误消息。把它放到一个单独的函数中已经得到了返回。

现在让我们修复saveHandler:

func saveHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/save/"):]
    body := r.FormValue("body")
    p := &Page{Title: title, Body: []byte(body)}
    err := p.save()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

p.save()期间发生的任何错误都会报告给用户。

以上这段代码的效率不高:renderTemplate每次渲染页面时都调用ParseFiles。更好的方法是在程序初始化时调用ParseFiles,将所有模板解析为单个*模板。然后,我们可以使用ExecuteTemplate方法来呈现特定的模板。

首先,我们创建一个名为templates的全局变量,并使用ParseFiles初始化它。

var templates = template.Must(template.ParseFiles("edit.html", "view.html"))

template.Must是一个方便的包装器,当传入一个非nil的错误值时,程序会进行包裹,否则会不加修改地返回模板。在这里是合适的;如果模板不能被加载,唯一明智的做法是退出程序。

ParseFiles函数接受任意数量的字符串参数,这些参数标识我们的模板文件,并将这些文件解析为以基文件名命名的模板。如果要向程序中添加更多模板,则需要将它们的名称添加到ParseFiles调用的参数中。

然后我们修改renderTemplate函数来调用模板。带有相应模板名称的ExecuteTemplate方法:

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
    err := templates.ExecuteTemplate(w, tmpl+".html", p)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

注意,模板名称是模板文件名,所以我们必须在tmpl参数后附加.html

总结

  本节主要介绍了一个如何将我们的页面模块应用性增加,面对未知发生的错误,我们尽可能的去规避。