我正在使用Go gin框架杜松子酒
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Content-Type", "application/json")
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Max-Age", "86400")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Max")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(200)
} else {
c.Next()
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有状态码:200 OK,但OPTIONS请求后没有任何反应.看起来我想念一些东西,但我无法理解我错在哪里.
有谁能够帮我?
我正在使用Gin,https: //gin-gonic.github.io/gin/,用Golang构建一个简单的RESTful JSON API.
路线设置如下:
func testRouteHandler(c *gin.Context) {
// do smth
}
func main() {
router := gin.Default()
router.GET("/test", testRouteHandler)
router.Run(":8080")
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如何将参数传递给testRouteHandler函数?例如,公共数据库连接可能是想要在路由之间重用的东西.
在全局变量中使用它的最佳方法是什么?或者Go中有一些方法可以将额外的变量传递给testRouteHandler函数吗?Go中的函数是否有可选参数?
PS.我刚刚开始学习Go,所以可能是一些我很想念的东西:)
我想获取每个路由上的所有 http 错误,而无需每次重写 if 400 then if 404 then if 500 then 等等...所以我ErrorHandler()在每个路由处理程序中都有一个函数:
func (h *Handler) List(c *gin.Context) {
movies, err := h.service.ListService()
if err != nil {
utils.ErrorHandler(c, err)
return
}
c.JSON(http.StatusOK, movies)
}
Run Code Online (Sandbox Code Playgroud)
这个函数看起来像这样:
func ErrorHandler(c *gin.Context, err error) {
if err == ErrNotFound {
// 404
c.JSON(http.StatusNotFound, gin.H{"error": ErrNotFound.Error()})
} else if err == ErrInternalServerError {
// 500
c.JSON(http.StatusInternalServerError, gin.H{"error": ErrInternalServerError.Error()})
} // etc...
}
Run Code Online (Sandbox Code Playgroud)
ErrNotFound或者ErrInternalServerError只是像这样初始化的全局变量:
var ErrNotFound = errors.New(http.StatusText(http.StatusNotFound)) // 404 …Run Code Online (Sandbox Code Playgroud) 我在Gin中设置了默认路由器和一些路由:
router := gin.Default()
router.POST("/users", save)
router.GET("/users",getAll)
Run Code Online (Sandbox Code Playgroud)
但是如何处理杜松子酒中没有找到404路线?
最初,我使用的是我理解Gin使用的httprouter,所以这就是我原来的...
router.NotFound = http.HandlerFunc(customNotFound)
Run Code Online (Sandbox Code Playgroud)
和功能:
func customNotFound(w http.ResponseWriter, r *http.Request) {
//return JSON
return
}
Run Code Online (Sandbox Code Playgroud)
但这不适用于杜松子酒.
我需要能够使用以下命令返回JSON,c *gin.Context以便我可以使用:
c.JSON(404, gin.H{"code": "PAGE_NOT_FOUND", "message": "Page not found"})
Run Code Online (Sandbox Code Playgroud) 我正在设置测试Go。
我用go-sqlmockGo Gin 作为框架来测试 mysql 连接。现在我尝试测试mysql插入逻辑。
问题是我需要设置稍后gin.Context使用的模拟BindJSON。但到目前为止
我还不能设置这个。gin.Context
server side: golang
db: mysql
web framework: gin
Run Code Online (Sandbox Code Playgroud)
道戈
server side: golang
db: mysql
web framework: gin
Run Code Online (Sandbox Code Playgroud)
dao_test.go
unc PostImageToDBDao(c *gin.Context, db *sql.DB) {
// Because of this logic, I need to set gin.Context with json
var imageData util.ImageData
c.BindJSON(&imageData)
for _, imageName := range imageData.IMAGENAMES {
ins, err := db.Prepare("INSERT INTO images(article_uuid, image_name) VALUES(?,?)")
if err != nil {
log.Fatal(err)
}
ins.Exec(imageData.ARTICLEUUID, …Run Code Online (Sandbox Code Playgroud) 我有一个这样的控制器功能......
func GetMaterialByFilter(c *gin.Context) {
queryParam := weldprogs.QueryParam{}
c.BindQuery(&queryParam)
materialByFilter, getErr := services.WeldprogService.GetMaterialByFilter(&queryParam)
if getErr != nil {
//TODO : Handle user creation error
c.JSON(getErr.Status, getErr)
return
}
c.JSON(http.StatusOK, materialByFilter)
}
Run Code Online (Sandbox Code Playgroud)
QueryParam 结构是这样的..
type QueryParam struct {
Basematgroup_id []string `form:"basematgroup_id"`
License_id []string `form:"license_id"`
Diameter_id []string `form:"diameter_id"`
Gasgroup_id []string `form:"gasgroup_id"`
Wiregroup_id []string `form:"wiregroup_id"`
Wiremat_id []string `form:"wiremat_id"`
}
Run Code Online (Sandbox Code Playgroud)
我的测试功能是这样的..
func TestGetMaterialByFilter(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
GetMaterialByFilter(c)
assert.Equal(t, 200, w.Code)
var got gin.H
err := json.Unmarshal(w.Body.Bytes(), &got)
if …Run Code Online (Sandbox Code Playgroud) 我想将我的路线分组在不同的文件中,这样主文件就不会很混乱。
我想在他们自己的文件中添加类似的内容:
v1 := router.Group("/v1")
{
v1.Group("users", usersRoutes)
v1.Group("pictures", picturesRoutes)
v1.Group("friends", friendsRoutes)
}
Run Code Online (Sandbox Code Playgroud)
所以每一个*Routes看起来都是这样的:
users := v1.Group("/users")
{
users.GET("/", getUsers)
users.POST("/", createUser)
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?现在我的代码如下所示:
package app
import (
"net/http"
"github.com/gin-gonic/gin"
)
func getUrls() {
v1 := router.Group("/v1")
{
ping := v1.Group("/ping")
{
ping.GET("/", pongFunction)
}
users := v1.Group("/users")
{
users.GET("/", getUsersFunction)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这将大大增加其规模。
基本信息
我正在开发一个基于go和gin编写的小型Web项目.这是我的golang代码.运行后,go run test.go我们有一个Web服务器,正在监听8089.
Golang test.go
package main
import "github.com/gin-gonic/gin"
import "net/http"
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*")
router.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{
"scheme": "http",
"domain": "meican.loc",
})
})
router.Run(":8089") // listen and serve on 0.0.0.0:8089
}
Run Code Online (Sandbox Code Playgroud)
后端生成的html代码应该包含前端javascript引擎使用的模板(比方说Angular.js).
所以模板代码在script标签中,就像这样:
template/index.html的一部分
<script type="text/template" charset="utf-8">
<div data="{{.scheme}}://{{.domain}}/qr"></div>
<div data="{{.scheme}}://{{.domain}}/qr"></div> <!-- problem here -->
</script>
Run Code Online (Sandbox Code Playgroud)
当{{.domain}}第二次使用时,我得到了不同的结果.我刷新了浏览器并检查了源代码.然后我得到了这个:
浏览器源代码结果
<script type="text/template" charset="utf-8">
<div data="http://meican.loc/qr"></div>
<div data="http://"meican.loc"/qr"></div> …Run Code Online (Sandbox Code Playgroud) 我需要在杜松子酒的中间件中记录响应主体,但我找不到如何获取响应主体.有人可以帮忙吗?
我正在使用这样的中间件:
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
statusCode := c.Writer.Status()
if statusCode >= 400 {
//ok this is an request with error, let's make a record for it
//log body here
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何从中间件中获取Context的响应体?
我正在使用 Go Gin 设置一个小型 API,但是我无法说服记录器输出 JSON。默认情况下它是一个键/值字符串,但我需要它作为 json。
我怎样才能做到这一点?我觉得它应该很容易支持,但我一直在努力使用自定义格式化功能,我需要自己考虑各种参数。
或者,我也使用 uber/zap 记录器手动记录,但我还没有找到用我的记录器替换 gin 记录器的方法。
任何指点都将不胜感激,因为 gin 的 github 上的文档并没有太大帮助。
谢谢!
编辑:澄清一下,添加中间件有助于记录请求,但我正在寻找为 Gin 设置 JSON 日志记录的单点(例如:包括与请求无关的日志,例如框架内部的调试/信息日志)
go ×10
go-gin ×10
unit-testing ×2
cors ×1
frameworks ×1
go-sqlmock ×1
go-templates ×1
html ×1
preflight ×1