add a method to set the indentJsonIndentString used in Context.IndentedJSON

This commit is contained in:
bestgopher 2020-05-01 18:17:29 +08:00
parent 4427ca4a60
commit 2fc888a61d
5 changed files with 63 additions and 14 deletions

View File

@ -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.

13
gin.go
View File

@ -11,6 +11,7 @@ import (
"net/http"
"os"
"path"
"strings"
"sync"
"github.com/gin-gonic/gin/internal/bytesconv"
@ -19,6 +20,9 @@ import (
const defaultMultipartMemory = 32 << 20 // 32 MB
// A space string
var spaceString = string(32)
var (
default404Body = []byte("404 page not found")
default405Body = []byte("405 method not allowed")
@ -112,6 +116,7 @@ type Engine struct {
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) {

View File

@ -6,13 +6,16 @@ package gin
import (
"crypto/tls"
"encoding/json"
"fmt"
"html/template"
"io/ioutil"
"math/rand"
"net/http"
"net/http/httptest"
"reflect"
"strconv"
"strings"
"sync/atomic"
"testing"
"time"
@ -544,3 +547,35 @@ func assertRoutePresent(t *testing.T, gotRoutes RoutesInfo, wantRoute RouteInfo)
func handlerTest1(c *Context) {}
func handlerTest2(c *Context) {}
// Engine.IndentJsonIndentSpaceNum
func TestEngine_IndentJsonIndentSpaceNum(t *testing.T) {
rand.Seed(time.Now().UnixNano())
spaceNum := rand.Intn(10)
router := Default()
defaultResponse := H{"name": "test", "age": 20}
router.IndentJsonIndentSpaceNum(spaceNum)
router.GET("/test", func(c *Context) {
c.IndentedJSON(200, defaultResponse)
})
s := httptest.NewServer(router)
defer s.Close()
req, err := http.NewRequest("GET", "/test", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
router.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Fatal("error code: ", rr.Code)
}
except, _ := json.MarshalIndent(defaultResponse, "", strings.Repeat(spaceString, spaceNum))
assert.Equal(t, rr.Body.Bytes(), except)
t.Log(rr.Body.String())
}

View File

@ -21,6 +21,7 @@ type JSON struct {
// IndentedJSON contains the given interface object.
type IndentedJSON struct {
IndentString string
Data interface{}
}
@ -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
}

View File

@ -55,7 +55,7 @@ func TestRenderIndentedJSON(t *testing.T) {
"bar": "foo",
}
err := (IndentedJSON{data}).Render(w)
err := (IndentedJSON{" ", data}).Render(w)
assert.NoError(t, err)
assert.Equal(t, "{\n \"bar\": \"foo\",\n \"foo\": \"bar\"\n}", w.Body.String())
@ -67,7 +67,7 @@ func TestRenderIndentedJSONPanics(t *testing.T) {
data := make(chan int)
// json: unsupported type: chan int
err := (IndentedJSON{data}).Render(w)
err := (IndentedJSON{"", data}).Render(w)
assert.Error(t, err)
}