通过postman测试Createdocument函数时一直返回500 Internal Server Error,没有其他附加内容,我先放出函数的具体内容
func Createdocument(c *gin.Context) {
db, _ := c.MustGet("db").(*sql.DB)
document := new(Document)
if err := c.ShouldBindJSON(&document); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"})
return
}
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS documents (
Id INT AUTO_INCREMENT PRIMARY KEY,
Title VARCHAR(255) NOT NULL,
Content TEXT,
Visibility BOOLEAN NOT NULL DEFAULT FALSE,
OwnerID INT UNSIGNED NOT NULL,
shared_with JSON)`)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create table"})
return
}
userID := c.MustGet("userID").(int)
_, err = db.Exec(`INSERT INTO documents (Title, Content, OwnerID, Visibility, shared_with) VALUES (?, ?, ?, ?, ?)`,
document.Title, document.Content, userID, document.Visibility, document.SharedWith)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Document created successfully"})
}
我检查了数据库,数据库中的 documents 表结构与代码中的定义一致。传入错误的请求也正常的返回400,从十点一直被这个问题卡到现在,真的不知道怎么办了
下面是程序的全部代码(程序的内容是一个在线文档编辑系统)
main.go
package main
import (
"Gocument/Dao"
"Gocument/api"
"database/sql"
"github.com/gin-gonic/gin"
_ "github.com/go-sql-driver/mysql"
)
var DB *sql.DB
type User struct {
ID int `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
}
func main() {
dsn := "root:qweasdzxc@tcp(127.0.0.1:3306)/woop?charset=utf8mb4&parseTime=True&loc=Local"
var err error
DB, err = sql.Open("mysql", dsn)
if err != nil {
panic("failed to connect database")
}
defer DB.Close()
DB.Exec(`CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL)`)
r := gin.Default()
r.Use(DBMiddleware(DB))
r.POST("/register", api.Register)
r.POST("/login", api.Login)
r.GET("/logout", api.Logout)
r.POST("/createdocument", Dao.Createdocument)
r.POST("/inquire", Dao.Inquire)
r.POST("/edit", Dao.Edit)
r.POST("/share", Dao.Share)
r.Run(":8080")
}
func DBMiddleware(db *sql.DB) gin.HandlerFunc {
return func(c *gin.Context) {
c.Set("db", db)
c.Next()
}
}
/Dao/Document.go
package Dao
import (
"database/sql"
"github.com/gin-gonic/gin"
"net/http"
)
var username string
var userID int
var ifICanSee bool
type Document struct {
ID uint `json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Visibility bool `json:"visibility"`
OwnerID uint `json:"owner_id"`
SharedWith []string `json:"shared_with"`
}
func Createdocument(c *gin.Context) {
db, _ := c.MustGet("db").(*sql.DB)
document := new(Document)
if err := c.ShouldBindJSON(&document); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"})
return
}
_, err := db.Exec(`
CREATE TABLE IF NOT EXISTS documents (
Id INT AUTO_INCREMENT PRIMARY KEY,
Title VARCHAR(255) NOT NULL,
Content TEXT,
Visibility BOOLEAN NOT NULL DEFAULT FALSE,
OwnerID INT UNSIGNED NOT NULL,
shared_with JSON)`)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create table"})
return
}
userID := c.MustGet("userID").(int)
_, err = db.Exec(`INSERT INTO documents (Title, Content, OwnerID, Visibility, shared_with) VALUES (?, ?, ?, ?, ?)`,
document.Title, document.Content, userID, document.Visibility, document.SharedWith)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Document created successfully"})
}
func Inquire(c *gin.Context) {
ifICanSee = false
db, _ := c.MustGet("db").(*sql.DB)
c.JSON(200, "查询与编辑")
var id int
c.ShouldBindJSON(&id)
var document Document
db.QueryRow("SELECT * FROM documents WHERE ID = ?", id).Scan(document)
for _, value := range document.SharedWith {
username := c.MustGet("username").(string)
if value == username {
ifICanSee = true
}
}
if document.Visibility == false && ifICanSee == false {
c.JSON(500, "you are not allowed to read or edit it")
return
}
c.JSON(200, document)
}
func Edit(c *gin.Context) {
ifICanSee = false
db, _ := c.MustGet("db").(*sql.DB)
var document Document
if err := c.ShouldBindJSON(&document); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
for _, value := range document.SharedWith {
username := c.MustGet("username").(string)
if value == username {
ifICanSee = true
}
}
if document.Visibility == false && ifICanSee == false {
c.JSON(500, "you are not allowed to read or edit it")
return
}
_, err := db.Exec("UPDATE documents SET Title = ?, Content = ? WHERE ID = ?", document.Title, document.Content, document.ID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": " 上传失败"})
return
}
}
func Share(c *gin.Context) {
db, _ := c.MustGet("db").(*sql.DB)
var shareRequest struct {
ID uint `json:"id"`
ShareWith string `json:"share_with"`
}
if err := c.ShouldBindJSON(&shareRequest); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request data"})
return
}
userID = c.MustGet("userID").(int)
_, err := db.Exec("UPDATE documents SET shared_with = JSON_ARRAY_APPEND(shared_with, '$', ?) WHERE ID = ? AND OwnerID = ?",
shareRequest.ShareWith, shareRequest.ID, userID)
/*
JSON_ARRAY_APPEND 是一个 SQL 函数,用于向 JSON 数组中添加元素。
shared_with 是要操作的 JSON 字段。
'$' 表示 JSON 路径,'$' 表示从 JSON 的根开始。
*/
if err != nil {
panic(err)
}
c.JSON(http.StatusOK, gin.H{"message": "Document shared successfully"})
}
/api/login.go
package api
import (
"database/sql"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
var UserID int
var Username string
type User struct {
ID int `json:"id"`
Username string `json:"username"`
Password string `json:"password"`
}
func Login(c *gin.Context) {
DB, _ := c.MustGet("db").(*sql.DB)
user := new(User)
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
var userY User
err := DB.QueryRow("SELECT id, username, password FROM users WHERE username = ?", user.Username).Scan(&userY.ID, &userY.Username, &userY.Password)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
return
}
if user.Password != userY.Password {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid username or password"})
return
}
cookie := &http.Cookie{
Name: "sessionID",
Value: fmt.Sprintf("%d", user.ID), // 将用户的ID作为Cookie的值
Expires: time.Now().Add(24 * time.Hour), // 设置Cookie的过期时间为当前时间后的24小时
HttpOnly: true, // Cookie只能通过HTTP协议访问
}
http.SetCookie(c.Writer, cookie) // 将Cookie写入HTTP响应头中
c.JSON(200, gin.H{"good": "welcome"})
c.Set("userID", userY.ID)
c.Set("username", user.Username)
return
}
func Register(c *gin.Context) {
DB, _ := c.MustGet("db").(*sql.DB)
var user User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
_, err := DB.Exec(`INSERT INTO users (username, password) VALUES (?, ?)`, user.Username, user.Password)
if err != nil {
c.JSON(400, gin.H{"error": "Failed to register"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "User registered successfully"})
}
func Logout(c *gin.Context) {
// 创建一个空的Cookie,并设置其过期时间为过去的时间
cookie := &http.Cookie{
Name: "sessionID",
Value: "",
Expires: time.Unix(0, 0), // 设置Cookie的过期时间为1970-01-01 00:00:00 UTC,这是一个过去的时间
HttpOnly: true,
}
http.SetCookie(c.Writer, cookie)
c.JSON(http.StatusOK, gin.H{"message": "Logout successful"})
}
麻烦大家轻一点喷(