这是我参与「第五届青训营 」伴学笔记创作活动的第3天。
主要是写第二天的作业当中发布帖子的操作。由于个人水平比较差,可能实现发帖的代码不是很好。
一、server.go
server.go中添加的代码跟视频之前查询帖子的代码大致相同,区别在于这里使用的时Query方法来获取url中?之后的请求参数。如在网页当中输入localhost:8080/community/page?title=发帖&context=我要发贴,则server端能够获取title和context里面的信息
r.GET("/community/page", func(c *gin.Context){
title := c.Query("title")
context := c.Query("context")
data := controller.QueryPageAdd(title, context)
c.JSON(200, data)
})
这里cotroller.QueryPageAdd方法是跟前面cotroller.QueryPageInfo类似,判断网页返回信息是否有错误。
二、cotroller.QueryPageAdd
这里我图方便,直接把该方法放在cotorller文件夹下的query_page_info.go中。由于不像前文需要返回回复帖子,因此当发帖成功时我只需要告知用户该帖子发布成功即可。
func QueryPageAdd(title string, context string) *PageData {
err := service.QueryPageAdd(title, context)
if err != nil {
return &PageData{
Code: -1,
Msg: err.Error(),
}
}
return &PageData{
Code: 0,
Msg: "success",
Data: title+"帖子发布成功",
}
}
三、service.QueryPageAdd
这里我在service中新建了一个query_page_add.go,把QueryPageAdd方法放入该文件下。
package service
import (
"encoding/json"
"os"
"time"
repository "work/2/gin_web/respository"
)
func QueryPageAdd(title string, context string) error {
TopicDao := repository.NewTopicDaoInstance()
n := TopicDao.QueryTopicAll() + 1
id := int64(n)
tim := time.Now().Unix()
topic := repository.Topic{id, title, context, tim}
st, err := json.Marshal(topic)
if err != nil {
return err
}
file, err := os.OpenFile("data/topic", os.O_APPEND, 0)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString("\n")
if err != nil {
return err
}
_, err = file.Write(st)
if err != nil {
return err
}
if err := repository.Init("data/"); err != nil {
os.Exit(-1)
}
return nil
}
首先,n是统计topic中有多少话题数,n+1的值作为id的结果,这样就保证本地id生成不重复。由于Topic结构体中id是int64类型,这里要转换数据类型。tim := time.Now().Unix()是获取create_time信息。
TopicDao := repository.NewTopicDaoInstance()
n := TopicDao.QueryTopicAll() + 1
id := int64(n)
tim := time.Now().Unix()
然后将结果序列化为json格式
topic := repository.Topic{id, title, context, tim}
st, err := json.Marshal(topic)
if err != nil {
return err
}
将json格式的数据写入topic文件。
file, err := os.OpenFile("data/topic", os.O_APPEND, 0)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString("\n")
if err != nil {
return err
}
_, err = file.Write(st)
if err != nil {
return err
}
再次加载一下本地文件。如果此处不加载的话,直接搜索刚发布的帖子是搜索不到的。
if err := repository.Init("data/"); err != nil {
os.Exit(-1)
}
四、TopicDao.QueryTopicAll()
在respository文件夹中的topic.go文件最后加上这个方法,这是统计发布话题总数的方法,方便增加新的不冲突id。
func (*TopicDao) QueryTopicAll() int {
return len(topicIndexMap)
}
五、测试
打开浏览器输入网址测试发帖功能。
然后搜索该帖子id,也就是3,可以看到帖子已经能够搜索到。
查看本地topic文件,能够看到刚刚发布的帖子
查看服务端信息
总结
主要说一个比较大的问题
我中间遇到过topic和post文件报错,大概是反序列化那里会返回以下的错误信息,主要是json格式有问题。我到最后也没解决,但是代码还是能跑,后面也没有返回该错误信息。只是打开两个文件还是会提示图中的错误。
invalid character '{' after top-level value
topic文件如图中所示,第二行会出现红波浪线
最后,由于个人水平有限,实现作业的方法可能非常糟糕。再加上第三题Map的并发安全问题看不懂,只能写到这里,有没有大佬能帮忙指点一下。