龙空技术网

8.Go语言编写个人博客 发布文章

ITTale 68

前言:

今天同学们对“个人博客网站毕业设计八千”大致比较关切,你们都需要学习一些“个人博客网站毕业设计八千”的相关文章。那么小编也在网络上网罗了一些有关“个人博客网站毕业设计八千””的相关知识,希望姐妹们能喜欢,朋友们快快来了解一下吧!

上一节完成了用户登录。本节我们来编写发布文章。

首先在models目录中创建一下文件article.go,用它来编写article模型。

package modelsimport (	"gorm.io/gorm")type Article struct {	gorm.Model	Title   string `gorm:"type:varchar(255);not null" json:"title"`	Content string `gorm:"type:text;not null" json:"content"`	UserID  uint   `gorm:"not null" json:"user_id"`	User    User   `gorm:"foreignKey:UserID"`}

这定义了一个名为Article的结构体,它将映射到数据库中的一个表,用来存储文章数据。结构体中的每个字段表示表中的一个列。前3个字段就不多介绍了。

User字段定义了与User结构体的关联,这里使用了GORM的foreignKey标签来指定外键:

gorm:"foreignKey:UserID": 表示User结构体通过UserID字段与Article结构体相关联。

接下修改models/db.go文件中的:err = db.AutoMigrate(&User{}, &Article{})增加&Article{}来确保程序运行时能创建Article模型对应的数据库表。

模型相关的代码编写完成后,我们把接口需要代码实现,在api目录中新建article.go文件:

package apiimport (	"net/http"	"xblog/models"	"github.com/gin-gonic/gin")// CreateArticle 创建新文章func CreateArticle(c *gin.Context) {	// 从上下文中获取当前用户	currentUser, _ := c.Get("currentUser")	user, ok := currentUser.(*models.JwtClaims)	if !ok {		c.JSON(http.StatusUnauthorized, gin.H{"error": "无法获取用户认证信息"})		return	}	// 初始化Article结构体	var article models.Article	// 绑定请求体到article结构体	if err := c.ShouldBindJSON(&article); err != nil {		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})		return	}	// 设置文章的UserID为当前用户的ID	article.UserID = user.UserID	// 保存文章到数据库	if result := models.DB.Create(&article); result.Error != nil {		c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})		return	}	// 预加载User数据	if result := models.DB.Preload("User").First(&article, article.ID); result.Error != nil {		c.JSON(http.StatusInternalServerError, gin.H{"error": "加载文章详情时出现错误"})		return	}	// 返回创建的文章	c.JSON(http.StatusOK, gin.H{"article": article})}

我从CreateArticle函数开始解释代码:

CreateArticle函数定义了如何处理创建文章的HTTP请求,它接收一个类型为*gin.Context的参数,这是Gin框架中用于处理HTTP请求和响应的上下文对象。通过c.Get("currentUser")从上下文中获取当前用户的信息。currentUser可以是在之前的请求处理中设置的,用于表示已经认证的用户。通过断言检查currentUser是否可以转换为*models.JwtClaims类型,如果不成功,则返回HTTP 401 Unauthorized状态码,并携带错误信息。你还记得currentUser这个变量是怎么来的吗?是的上一节中,验证通过后,我将用户信息设置到Context中,供后续处理函数使用。初始化article为models.Article类型的变量,准备绑定请求体中的数据。使用c.ShouldBindJSON(&article)将请求体的JSON数据绑定到article变量,如果有错误发生,则返回HTTP 400 Bad Request状态码,并携带错误信息。将当前用户的ID设置为文章的UserID字段,确保文章与创建它的用户关联。使用models.DB.Create(&article)将article保存到数据库中,如果保存过程中出现错误,则返回HTTP 500 Internal Server Error状态码,并携带错误信息。使用models.DB.Preload("User").First(&article, article.ID)预加载与文章关联的用户数据,并根据文章ID查询文章。如果查询过程中发生错误,则返回HTTP 500 Internal Server Error状态码,并携带错误信息。最后,如果文章成功创建且用户数据预加载成功,函数以HTTP 200 OK状态码返回创建的文章数据。

简单来说这个函数属于一个典型的CRUD(创建、读取、更新、删除)操作中的“创建”操作,它使用Gin框架和GORM库来处理HTTP请求并与数据库交互。

最后我们把路由写一下。

package routerimport (	"xblog/api"	"xblog/utils"	"github.com/gin-gonic/gin")func InitRouter() {	// 创建默认路由实例	r := gin.Default()	// 配置路由	public := r.Group("api/v1")	{		public.POST("user/add", api.UserAdd)		public.POST("user/login", api.UserLogin)	}	// 配置需要认证的路由	protected := r.Group("api/v1")	protected.Use(utils.RequireAuth)	{		protected.POST("article/create", api.CreateArticle)	}	r.Run(":8000")}

以上是router.go文件中的全部内容,只有22-26这几行是新增的。我们来逐一解释一下:

protected := r.Group("api/v1") - 创建一个名为protected的路由组,同样以api/v1作为前缀。protected.Use(utils.RequireAuth) - 给protected路由组添加一个中间件utils.RequireAuth,这个中间件是用来确保请求已经通过了认证。任何属于这个组的路由都需要用户被认证后才可访问。在protected路由组中,配置了一个POST请求的路由: protected.POST("article/create", api.CreateArticle): 当请求POST /api/v1/article/create时,将调用api.CreateArticle函数来处理。

这个InitRouter函数是设置Gin路由的标准方式,它通过路由组和中间件提供了灵活的路由管理功能。通过区分public和protected路由组,可以很容易地管理哪些API端点是公开的,哪些需要用户认证。

到这里发布文章的代码就都完成了。让我们来运行程序,使用curl测试一下:

从上图可以看出,先使用curl模拟用户登录,并获取token。然后再次使用curl并且需要携带token才能发布文章。

好,没有问题。让我们登录MySQL查看一下数据。

很好,数据成功写入了数据库。

标签: #个人博客网站毕业设计八千