mirror of https://github.com/gin-gonic/gin.git
add a method to set the indentJsonIndentString used in Context.IndentedJSON
This commit is contained in:
parent
4427ca4a60
commit
2fc888a61d
|
@ -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.
|
||||
|
|
33
gin.go
33
gin.go
|
@ -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")
|
||||
|
@ -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) {
|
||||
|
|
35
gin_test.go
35
gin_test.go
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue