Optimize JSON.render renderer code

This commit is contained in:
朱宗辉 2024-11-17 16:09:14 +08:00
parent 6144ce5af3
commit 87ce468c78
2 changed files with 9 additions and 31 deletions

View File

@ -52,26 +52,6 @@ const ContextRequestKey ContextKeyType = 0
// abortIndex represents a typical value used in abort functions. // abortIndex represents a typical value used in abort functions.
const abortIndex int8 = math.MaxInt8 >> 1 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, // 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. // manage the flow, validate the JSON of a request and render a JSON response for example.
type Context struct { type Context struct {
@ -111,14 +91,14 @@ type Context struct {
// the browser to send this cookie along with cross-site requests. // the browser to send this cookie along with cross-site requests.
sameSite http.SameSite sameSite http.SameSite
// jsonRenderName the name of the JSON render currently used. The default value is render.JSON // jsonRender the JSON renderer currently used. The default value is render.JSON,
// this is used to get the JSON render type when executing the c.JSON function. // which is used to get the JSON rendering type when executing the c.JSON function.
jsonRenderName string jsonRender func(data any) render.Render
} }
// SetJSONRender set the name of the current JSON render // SetJSONRender set the current JSON render
func (c *Context) SetJSONRender(jsonRenderName string) { func (c *Context) SetJSONRender(jsonRender func(data any) render.Render) {
c.jsonRenderName = jsonRenderName c.jsonRender = jsonRender
} }
/************************************/ /************************************/
@ -139,8 +119,7 @@ func (c *Context) reset() {
c.formCache = nil c.formCache = nil
c.sameSite = 0 c.sameSite = 0
// registering a default JSON renderer // registering a default JSON renderer
c.jsonRenderName = defaultJsonRenderName c.jsonRender = render.NewJSON
c.RegisterJsonRender(defaultJsonRenderName, render.NewJSON)
*c.params = (*c.params)[:0] *c.params = (*c.params)[:0]
*c.skippedNodes = (*c.skippedNodes)[:0] *c.skippedNodes = (*c.skippedNodes)[:0]
} }
@ -1127,7 +1106,7 @@ func (c *Context) JSONP(code int, obj any) {
// JSON serializes the given struct as JSON into the response body. // JSON serializes the given struct as JSON into the response body.
// It also sets the Content-Type as "application/json". // It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj any) { func (c *Context) JSON(code int, obj any) {
c.Render(code, createInstance(c.jsonRenderName, obj)) c.Render(code, c.jsonRender(obj))
} }
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string. // AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.

View File

@ -3146,8 +3146,7 @@ func NewMyJSON(data any) render.Render {
func TestCustomJSONRender(t *testing.T) { func TestCustomJSONRender(t *testing.T) {
w := httptest.NewRecorder() w := httptest.NewRecorder()
c, _ := CreateTestContext(w) c, _ := CreateTestContext(w)
c.RegisterJsonRender("MyTestJSON", NewMyJSON) c.SetJSONRender(NewMyJSON)
c.SetJSONRender("MyTestJSON")
c.JSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"}) c.JSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"})