golang中struct中大小写对gin框架的影响

发布于:2025-06-29 ⋅ 阅读:(22) ⋅ 点赞:(0)

1.问题描述

在编写gin框发起post请求时发现如下问题

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type Login struct {
	user    string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
	pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}

func main() {
	r := gin.Default()
	r.POST("loginJSON", func(ctx *gin.Context) {
		var json Login
		if err := ctx.ShouldBindJSON(&json); err != nil {
			// gin.H封装了生成json数据的工具
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		fmt.Println("json.user:", json.user, "json.pssword:", json.pssword)
		if json.user != "root" || json.pssword != "admin" {
			ctx.JSON(http.StatusBadRequest, gin.H{"status": 304})
			return
		}
		ctx.JSON(http.StatusOK, gin.H{"status": 200})
	})
	r.Run(":8001")
}

执行之后访问本地接口如下所示

curl http://127.0.0.1:8001/loginJSON -H 'content-type:application/json' -d "{\"user\":\"root\",\"password\":\"admin111\"}" -X POST
{"status":"304"}

控制台输出如下

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

[GIN-debug] POST   /loginJSON                --> main.main.func1 (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8001
json.user:  json.pssword: 

可以看到账号密码未打印出来

2.大小写在struct中的影响

1. 字段可访问性
首字母大写的字段(如 User, Pssword):
是可导出(Exported)的,可以被其他包访问。
序列化/反序列化库(如 JSON、XML、Gin 的 binding 等)可以正常读写这些字段。
首字母小写的字段(如 user, pssword):
是不可导出(Unexported)的,只能在当前包内访问。
外部库(如 JSON 编码器、Gin 的表单绑定器)无法直接访问这些字段,会导致序列化/反序列化失败。

Gin框架无法正常读写字段,修改之后

3.问题修正

package main

import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

type Login struct {
	User    string `form:"username" json:"user" uri:"user" xml:"user" binding:"required"`
	Pssword string `form:"password" json:"password" uri:"password" xml:"password" binding:"required"`
}

func main() {
	r := gin.Default()
	r.POST("loginJSON", func(ctx *gin.Context) {
		var json Login
		if err := ctx.ShouldBindJSON(&json); err != nil {
			// gin.H封装了生成json数据的工具
			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		fmt.Println("json.user:", json.User, "json.pssword:", json.Pssword)
		if json.User != "root" || json.Pssword != "admin" {
			ctx.JSON(http.StatusBadRequest, gin.H{"status": 304})
			return
		}
		ctx.JSON(http.StatusOK, gin.H{"status": 200})
	})
	r.Run(":8001")
}
C:\Users\PC>curl http://127.0.0.1:8001/loginJSON -H 'content-type:application/json' -d "{\"user\":\"root\",\"password\":\"admin\"}" -X POST
{"status":200}

可以看到访问已经正常,控制台输出也是正常的,问题解决