diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..9f5a98be --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/context.go b/context.go index a2384c0e..b5a7885f 100644 --- a/context.go +++ b/context.go @@ -859,7 +859,7 @@ func (c *Context) HTML(code int, name string, obj interface{}) { // WARNING: we recommend to use this only for development purposes since printing pretty JSON is // more CPU and bandwidth consuming. Use Context.JSON() instead. func (c *Context) IndentedJSON(code int, obj interface{}) { - c.Render(code, render.IndentedJSON{Data: obj}) + c.Render(code, render.IndentedJSON{IndentString: c.engine.indentJsonIndentString, Data: obj}) } // SecureJSON serializes the given struct as Secure JSON into the response body. diff --git a/gin.go b/gin.go index 1c2acbc8..2e4cdb8c 100644 --- a/gin.go +++ b/gin.go @@ -11,6 +11,7 @@ import ( "net/http" "os" "path" + "strings" "sync" "github.com/gin-gonic/gin/internal/bytesconv" @@ -25,6 +26,9 @@ var ( defaultAppEngine bool ) +// A space string +var spaceString = string(32) + // HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context) @@ -102,16 +106,17 @@ type Engine struct { // See the PR #1817 and issue #1644 RemoveExtraSlash bool - delims render.Delims - secureJsonPrefix string - HTMLRender render.HTMLRender - FuncMap template.FuncMap - allNoRoute HandlersChain - allNoMethod HandlersChain - noRoute HandlersChain - noMethod HandlersChain - pool sync.Pool - trees methodTrees + delims render.Delims + secureJsonPrefix string + HTMLRender render.HTMLRender + FuncMap template.FuncMap + allNoRoute HandlersChain + allNoMethod HandlersChain + noRoute HandlersChain + noMethod HandlersChain + pool sync.Pool + trees methodTrees + indentJsonIndentString string } var _ IRouter = &Engine{} @@ -145,6 +150,7 @@ func New() *Engine { trees: make(methodTrees, 0, 9), delims: render.Delims{Left: "{{", Right: "}}"}, secureJsonPrefix: "while(1);", + indentJsonIndentString: strings.Repeat(spaceString, 4), } engine.RouterGroup.engine = engine engine.pool.New = func() interface{} { @@ -177,6 +183,13 @@ func (engine *Engine) SecureJsonPrefix(prefix string) *Engine { return engine } +// IndentJsonIndentSpaceNum sets the indentJsonIndentString used in Context.IndentedJSON. +// When we use Context.IndentedJSON, we can use custom indentation to render the response. +func (engine *Engine) IndentJsonIndentSpaceNum(spaceNum int) *Engine { + engine.indentJsonIndentString = strings.Repeat(spaceString, spaceNum) + return engine +} + // LoadHTMLGlob loads HTML files identified by glob pattern // and associates the result with HTML renderer. func (engine *Engine) LoadHTMLGlob(pattern string) { diff --git a/render/json.go b/render/json.go index 015c0dbb..7e771423 100644 --- a/render/json.go +++ b/render/json.go @@ -21,7 +21,8 @@ type JSON struct { // IndentedJSON contains the given interface object. type IndentedJSON struct { - Data interface{} + IndentString string + Data interface{} } // SecureJSON contains the given interface object and its prefix. @@ -80,7 +81,7 @@ func WriteJSON(w http.ResponseWriter, obj interface{}) error { // Render (IndentedJSON) marshals the given interface object and writes it with custom ContentType. func (r IndentedJSON) Render(w http.ResponseWriter) error { r.WriteContentType(w) - jsonBytes, err := json.MarshalIndent(r.Data, "", " ") + jsonBytes, err := json.MarshalIndent(r.Data, "", r.IndentString) if err != nil { return err }