Skip to content

Commit

Permalink
Fix issue gin-gonic#4094:By using structure encapsulation parameters …
Browse files Browse the repository at this point in the history
…to achieve the purpose of user-defined JSON rendering, while not changing the functions implemented by the original code

Signed-off-by: 朱宗辉 <[email protected]>
  • Loading branch information
ChenPuChu committed Nov 15, 2024
1 parent 75eefd4 commit ea10366
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion context.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ const ContextRequestKey ContextKeyType = 0
// abortIndex represents a typical value used in abort functions.
const abortIndex int8 = math.MaxInt8 >> 1

// defaultJsonRenderName, default JSON render name
const defaultJsonRenderName string = "render.JSON"

// jsonRenderRegistry, storing JSON render types and their corresponding creation factory functions
var jsonRenderRegistry = make(map[string]func(data any) render.Render)

// RegisterJsonRender allows users to register JSON render factory functions
func (c *Context) RegisterJsonRender(name string, jsonRender func(data any) render.Render) {
jsonRenderRegistry[name] = jsonRender
}

// createInstance, Create a JSON render instance through a factory function
func createInstance(name string, data any) render.Render {
jsonRender, exists := jsonRenderRegistry[name]
if !exists {
return jsonRenderRegistry[defaultJsonRenderName](data)
}
return jsonRender(data)
}

// Context is the most important part of gin. It allows us to pass variables between middleware,
// manage the flow, validate the JSON of a request and render a JSON response for example.
type Context struct {
Expand Down Expand Up @@ -90,6 +110,15 @@ type Context struct {
// sameSite allows a server to define a cookie attribute making it impossible for
// the browser to send this cookie along with cross-site requests.
sameSite http.SameSite

// jsonRenderName the name of the JSON render currently used. The default value is render.JSON
// this is used to get the JSON render type when executing the c.JSON function.
jsonRenderName string
}

// SetJSONRender set the name of the current JSON render
func (c *Context) SetJSONRender(jsonRenderName string) {
c.jsonRenderName = jsonRenderName
}

/************************************/
Expand All @@ -109,6 +138,9 @@ func (c *Context) reset() {
c.queryCache = nil
c.formCache = nil
c.sameSite = 0
// registering a default JSON renderer
c.jsonRenderName = defaultJsonRenderName
c.RegisterJsonRender(defaultJsonRenderName, render.NewJSON)
*c.params = (*c.params)[:0]
*c.skippedNodes = (*c.skippedNodes)[:0]
}
Expand Down Expand Up @@ -1095,7 +1127,7 @@ func (c *Context) JSONP(code int, obj any) {
// JSON serializes the given struct as JSON into the response body.
// It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj any) {
c.Render(code, render.JSON{Data: obj})
c.Render(code, createInstance(c.jsonRenderName, obj))
}

// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
Expand Down

0 comments on commit ea10366

Please sign in to comment.