type Page struct {
Title string `json:"title"`
Body string `json:"body"`
}
// ``符号为结构体的标准,可忽略
Page
结构体绑定方法:Save
// SavePage 页面文件保存方法,保存到数据库,这里保存到页面文件中
// 使用bufio操作文件
// notice: 延时关闭 flush
// 绑定Page指针变量
func (page *Page) SavePage(title string, body string) (err error) {
title += ".txt"
// todo 1. 拿到页面文件句柄
file, err := os.OpenFile(title, os.O_CREATE|os.O_RDWR, fs.ModePerm)
// todo final step
defer func() { _ = file.Close() }()
if err != nil {
fmt.Println("无法获取到页面文件,error:", err)
return err
}
// todo 2. 打开页面文件
writer := bufio.NewWriter(file)
// todo 3. 往页面文件写入内容
nByteNum, err := writer.Write([]byte(body))
if err != nil {
fmt.Println("页面文件保存失败,error:", err)
return err
}
// todo 4. 刷写数据出去
_ = writer.Flush()
fmt.Println("写入的内容大小为:", nByteNum, "字节")
return nil
}
内容添加文件后缀,固定为.txt
使用bufio操作文件,可以更换其它方式
*指针变量
注意事项:
延时关闭
defer func() { _ = file.Close() }()
数据刷写
_ = writer.Flush()
Page
结构体支持页面内容查看方法,同时提供页面文件是否存在的方法
// 判断是否存在该页面文件名,不需要加后缀!已经手动添加;也可以优化,多加入参数表示后缀即可
func ExistFile(fileName string) bool {
if _, err := os.Stat(fileName + ".txt"); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// 查看指定的页面文件内容
// 使用os操作文件
func ViewPage(title string) (page *Page) {
page = &Page{}
page.Title = title
if ExistFile(title) {
fileContent, err := os.ReadFile(title + ".txt")
if err != nil {
fmt.Println("读取页面文件出错, error is :", err)
} else {
page.Body = string(fileContent)
}
}
return page
}
entity/entity.go
文件的全部代码为:package entity
import (
"bufio"
"fmt"
"io/fs"
"os"
)
type Page struct {
Title string `json:"title"`
Body string `json:"body"`
}
// SavePage 页面文件保存方法,保存到数据库,这里保存到页面文件中
// 使用bufio操作文件
// notice: 延时关闭 flush
func (page *Page) SavePage(title string, body string) (err error) {
title += ".txt"
// todo 1. 拿到页面文件句柄
file, err := os.OpenFile(title, os.O_CREATE|os.O_RDWR, fs.ModePerm)
// todo final step
defer func() { _ = file.Close() }()
if err != nil {
fmt.Println("无法获取到页面文件,error:", err)
return err
}
// todo 2. 打开页面文件
writer := bufio.NewWriter(file)
// todo 3. 往页面文件写入内容
nByteNum, err := writer.Write([]byte(body))
if err != nil {
fmt.Println("页面文件保存失败,error:", err)
return err
}
// todo 4. 刷写数据出去
_ = writer.Flush()
fmt.Println("写入的内容大小为:", nByteNum, "字节")
return nil
}
// 判断是否存在该页面文件名,不需要加后缀!
func ExistFile(fileName string) bool {
if _, err := os.Stat(fileName + ".txt"); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// 查看指定的页面文件内容
// 使用os操作文件
func ViewPage(title string) (page *Page) {
page = &Page{}
page.Title = title
if ExistFile(title) {
fileContent, err := os.ReadFile(title + ".txt")
if err != nil {
fmt.Println("读取页面文件出错, error is :", err)
} else {
page.Body = string(fileContent)
}
}
return page
}
func main() {
// 验证你的结构体是否发生改变 - 指针变量
page := entity.ViewPage("TestPage")
fmt.Println(page)
page.Body = "change"
fmt.Println(page)
}
// http方式保存page
// 默认从请求体中获取内容作为body传入文件
// 直接调用/savePage的body默认值为:this is a default value
// 更新操作也会调用该方法,body值为 上传的请求体内容
func saveHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/savePage/"):]
// todo 2. 填充 body内容
page := &entity.Page{}
// important 本人在后面update会遇到坑,默认从请求体中获取body
// todo 2.1. 优先考虑从请求体获取body
body := request.FormValue("body")
// todo 2.2. 请求体为空串,则赋值默认值
if body == "" {
body = "this is a default value"
}
// todo 3. 将body值写入到页面文件
err := page.SavePage(title, body)
// todo 3.1. 展示写入结果
if err != nil {
_, _ = responseWriter.Write([]byte("页面文件保存不成功"))
fmt.Println("页面文件保存不成功,error is :", err)
return
} else {
message := "页面文件保存成功"
_, _ = responseWriter.Write([]byte(message))
fmt.Println(message)
}
}
func main() {
// url路径要对应,当然你也可以更改;
// 若修改viewPage,上面的viewHandler方法也要对应改变
http.HandleFunc("/savePage/", saveHandler)
err := http.ListenAndServe(":8989", nil)
if err != nil {
fmt.Println("端口异常")
}
}
运行程序,然后到浏览器访问:localhost:8989/viewPage/myFirst2
// http 方式查看特定的page内容
// 使用硬编码页面
func viewHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/viewPage/"):]
// todo 2. 判断是否已经存在该页面文件
if !entity.ExistFile(title) {
// todo 2.1. 不存在该页面文件就结束
fmt.Printf("不存在%v页面文件", title)
_, _ = responseWriter.Write([]byte("不存在该页面文件"))
return
}
// todo 2.2. 获取该页面的内容
page := entity.ViewPage(title)
body := []byte(page.Body)
// todo 3. 页面展示内容
_, _ = responseWriter.Write(body)
}
func main() {
// url路径要对应,当然你也可以更改;
// 若修改viewPage,上面的viewHandler方法也要对应改变
http.HandleFunc("/savePage/", saveHandler)
http.HandleFunc("/viewPage/", viewHandler)
err := http.ListenAndServe(":8989", nil)
if err != nil {
fmt.Println("端口异常")
}
}
运行程序,到浏览器输入 localhost:8989/viewPage/myFirst2
// http方式删除页面文件
func deleteHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/deletePage/"):]
// todo 2. 判断是否存在该页面文件
if !entity.ExistFile(title) {
_, _ = responseWriter.Write([]byte("页面文件不存在,无法删除"))
return
} else {
// todo 3. 移除页面文件
err := os.Remove(title + ".txt")
if err != nil {
_, _ = responseWriter.Write([]byte("页面文件删除异常,请检查你的权限,或者联系管理员"))
return
}
_, _ = responseWriter.Write([]byte("页面文件删除成功"))
}
}
func main() {
// url路径要对应,当然你也可以更改;
// 若修改viewPage,上面的viewHandler方法也要对应改变
http.HandleFunc("/savePage/", saveHandler)
http.HandleFunc("/viewPage/", viewHandler)
http.HandleFunc("/deletePage/", deleteHandler)
err := http.ListenAndServe(":8989", nil)
if err != nil {
fmt.Println("端口异常")
}
}
// http方式更新页面文件
func updateHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/updatePage/"):]
// todo 2. 查看该页面文件
page := entity.ViewPage(title)
// todo 3. 填充html页面,硬编码
fmt.Fprintf(responseWriter, "Editing %s
"+
// 直接调用了 saveHandler
// todo 4. 再次保存该页面文件
"+
"
"+
""+
"",
page.Title, page.Title, page.Body)
}
/savePage
的访问动作func main() {
// url路径要对应,当然你也可以更改;
// 若修改viewPage,上面的viewHandler方法也要对应改变
http.HandleFunc("/savePage/", saveHandler)
http.HandleFunc("/viewPage/", viewHandler)
http.HandleFunc("/deletePage/", deleteHandler)
http.HandleFunc("/updatePage/", updateHandler)
err := http.ListenAndServe(":8989", nil)
if err != nil {
fmt.Println("端口异常")
}
}
运行程序,到浏览器输入 localhost:8989/updatePage/myFirst2
package main
import (
"fmt"
"goland-setting/test/webapp/entity"
"net/http"
"os"
)
// http 方式查看特定的page
// 使用硬编码页面
func viewHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/viewPage/"):]
// todo 2. 判断是否已经存在该页面文件
if !entity.ExistFile(title) {
// todo 2.1. 不存在该页面文件就结束
fmt.Printf("不存在%v页面文件", title)
_, _ = responseWriter.Write([]byte("不存在该页面文件"))
return
}
// todo 2.2. 获取该页面的内容
page := entity.ViewPage(title)
body := []byte(page.Body)
// todo 3. 页面展示内容
_, _ = responseWriter.Write(body)
}
// http方式保存page
// 默认从请求体中获取body
// 直接调用/savePage的body默认值为:this is a default value
// 更新操作也会调用该方法,body值为 上传的请求体内容
func saveHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/savePage/"):]
// todo 2. 填充 body内容
page := &entity.Page{}
// important 本人在后面update会遇到坑,默认从请求体中获取body
// todo 2.1. 优先考虑从请求体获取body
body := request.FormValue("body")
// todo 2.2. 请求体为空串,则赋值默认值
if body == "" {
body = "this is a default value"
}
// todo 3. 将body值写入到页面文件
err := page.SavePage(title, body)
// todo 3.1. 展示写入结果
if err != nil {
_, _ = responseWriter.Write([]byte("页面文件保存不成功"))
fmt.Println("页面文件保存不成功,error is :", err)
return
} else {
message := "页面文件保存成功"
_, _ = responseWriter.Write([]byte(message))
fmt.Println(message)
}
}
// http方式删除页面文件
func deleteHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/deletePage/"):]
// todo 2. 判断是否存在该页面文件
if !entity.ExistFile(title) {
_, _ = responseWriter.Write([]byte("页面文件不存在,无法删除"))
return
} else {
// todo 3. 移除页面文件
err := os.Remove(title + ".txt")
if err != nil {
_, _ = responseWriter.Write([]byte("页面文件删除异常,请检查你的权限,或者联系管理员"))
return
}
_, _ = responseWriter.Write([]byte("页面文件删除成功"))
}
}
// http方式更新页面文件
func updateHandler(responseWriter http.ResponseWriter, request *http.Request) {
// todo 1. 在url中获取 page的title值
title := request.URL.Path[len("/updatePage/"):]
// todo 2. 查看该页面文件
page := entity.ViewPage(title)
// todo 3. 填充html页面
fmt.Fprintf(responseWriter, "Editing %s
"+
// 直接调用了 saveHandler
// todo 4. 再次保存该页面文件
"+
"
"+
""+
"",
page.Title, page.Title, page.Body)
}
func main() {
http.HandleFunc("/savePage/", saveHandler)
http.HandleFunc("/deletePage/", deleteHandler)
http.HandleFunc("/updatePage/", updateHandler)
http.HandleFunc("/viewPage/", viewHandler)
err := http.ListenAndServe(":8989", nil)
if err != nil {
fmt.Println("端口异常")
}
}
一个简单的webApp就完成了。
html/template
来渲染,这样会好很多。