Add map shortcut and ServeFormatted method in output

This commit is contained in:
Ruben Cid 2018-08-20 22:55:50 +02:00
parent 7e0649d661
commit 5c407ff2e3
10 changed files with 66 additions and 69 deletions

View File

@ -67,18 +67,18 @@ func init() {
// AdminIndex is the default http.Handler for admin module. // AdminIndex is the default http.Handler for admin module.
// it matches url pattern "/". // it matches url pattern "/".
func adminIndex(rw http.ResponseWriter, r *http.Request) { func adminIndex(rw http.ResponseWriter, _ *http.Request) {
execTpl(rw, map[interface{}]interface{}{}, indexTpl, defaultScriptsTpl) execTpl(rw, map[interface{}]interface{}{}, indexTpl, defaultScriptsTpl)
} }
// QpsIndex is the http.Handler for writing qbs statistics map result info in http.ResponseWriter. // QpsIndex is the http.Handler for writing qbs statistics map result info in http.ResponseWriter.
// it's registered with url pattern "/qbs" in admin module. // it's registered with url pattern "/qbs" in admin module.
func qpsIndex(rw http.ResponseWriter, r *http.Request) { func qpsIndex(rw http.ResponseWriter, _ *http.Request) {
data := make(map[interface{}]interface{}) data := make(map[interface{}]interface{})
data["Content"] = toolbox.StatisticsMap.GetMap() data["Content"] = toolbox.StatisticsMap.GetMap()
// do html escape before display path, avoid xss // do html escape before display path, avoid xss
if content, ok := (data["Content"]).(map[string]interface{}); ok { if content, ok := (data["Content"]).(M); ok {
if resultLists, ok := (content["Data"]).([][]string); ok { if resultLists, ok := (content["Data"]).([][]string); ok {
for i := range resultLists { for i := range resultLists {
if len(resultLists[i]) > 0 { if len(resultLists[i]) > 0 {
@ -104,7 +104,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{}) data := make(map[interface{}]interface{})
switch command { switch command {
case "conf": case "conf":
m := make(map[string]interface{}) m := make(M)
list("BConfig", BConfig, m) list("BConfig", BConfig, m)
m["AppConfigPath"] = appConfigPath m["AppConfigPath"] = appConfigPath
m["AppConfigProvider"] = appConfigProvider m["AppConfigProvider"] = appConfigProvider
@ -128,14 +128,14 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
execTpl(rw, data, routerAndFilterTpl, defaultScriptsTpl) execTpl(rw, data, routerAndFilterTpl, defaultScriptsTpl)
case "filter": case "filter":
var ( var (
content = map[string]interface{}{ content = M{
"Fields": []string{ "Fields": []string{
"Router Pattern", "Router Pattern",
"Filter Function", "Filter Function",
}, },
} }
filterTypes = []string{} filterTypes = []string{}
filterTypeData = make(map[string]interface{}) filterTypeData = make(M)
) )
if BeeApp.Handlers.enableFilter { if BeeApp.Handlers.enableFilter {
@ -173,7 +173,7 @@ func listConf(rw http.ResponseWriter, r *http.Request) {
} }
} }
func list(root string, p interface{}, m map[string]interface{}) { func list(root string, p interface{}, m M) {
pt := reflect.TypeOf(p) pt := reflect.TypeOf(p)
pv := reflect.ValueOf(p) pv := reflect.ValueOf(p)
if pt.Kind() == reflect.Ptr { if pt.Kind() == reflect.Ptr {
@ -196,11 +196,11 @@ func list(root string, p interface{}, m map[string]interface{}) {
} }
// PrintTree prints all registered routers. // PrintTree prints all registered routers.
func PrintTree() map[string]interface{} { func PrintTree() M {
var ( var (
content = map[string]interface{}{} content = M{}
methods = []string{} methods = []string{}
methodsData = make(map[string]interface{}) methodsData = make(M)
) )
for method, t := range BeeApp.Handlers.routers { for method, t := range BeeApp.Handlers.routers {
@ -291,12 +291,12 @@ func profIndex(rw http.ResponseWriter, r *http.Request) {
// Healthcheck is a http.Handler calling health checking and showing the result. // Healthcheck is a http.Handler calling health checking and showing the result.
// it's in "/healthcheck" pattern in admin module. // it's in "/healthcheck" pattern in admin module.
func healthcheck(rw http.ResponseWriter, req *http.Request) { func healthcheck(rw http.ResponseWriter, _ *http.Request) {
var ( var (
result []string result []string
data = make(map[interface{}]interface{}) data = make(map[interface{}]interface{})
resultList = new([][]string) resultList = new([][]string)
content = map[string]interface{}{ content = M{
"Fields": []string{"Name", "Message", "Status"}, "Fields": []string{"Name", "Message", "Status"},
} }
) )
@ -344,7 +344,7 @@ func taskStatus(rw http.ResponseWriter, req *http.Request) {
} }
// List Tasks // List Tasks
content := make(map[string]interface{}) content := make(M)
resultList := new([][]string) resultList := new([][]string)
var fields = []string{ var fields = []string{
"Task Name", "Task Name",

View File

@ -6,7 +6,7 @@ import (
) )
func TestList_01(t *testing.T) { func TestList_01(t *testing.T) {
m := make(map[string]interface{}) m := make(M)
list("BConfig", BConfig, m) list("BConfig", BConfig, m)
t.Log(m) t.Log(m)
om := oldMap() om := oldMap()
@ -18,8 +18,8 @@ func TestList_01(t *testing.T) {
} }
} }
func oldMap() map[string]interface{} { func oldMap() M {
m := make(map[string]interface{}) m := make(M)
m["BConfig.AppName"] = BConfig.AppName m["BConfig.AppName"] = BConfig.AppName
m["BConfig.RunMode"] = BConfig.RunMode m["BConfig.RunMode"] = BConfig.RunMode
m["BConfig.RouterCaseSensitive"] = BConfig.RouterCaseSensitive m["BConfig.RouterCaseSensitive"] = BConfig.RouterCaseSensitive

View File

@ -31,7 +31,10 @@ const (
PROD = "prod" PROD = "prod"
) )
//hook function to run // Map shortcut
type M map[string]interface{}
// Hook function to run
type hookfunc func() error type hookfunc func() error
var ( var (

View File

@ -48,15 +48,15 @@ func TestAssignConfig_02(t *testing.T) {
_BConfig := &Config{} _BConfig := &Config{}
bs, _ := json.Marshal(newBConfig()) bs, _ := json.Marshal(newBConfig())
jsonMap := map[string]interface{}{} jsonMap := M{}
json.Unmarshal(bs, &jsonMap) json.Unmarshal(bs, &jsonMap)
configMap := map[string]interface{}{} configMap := M{}
for k, v := range jsonMap { for k, v := range jsonMap {
if reflect.TypeOf(v).Kind() == reflect.Map { if reflect.TypeOf(v).Kind() == reflect.Map {
for k1, v1 := range v.(map[string]interface{}) { for k1, v1 := range v.(M) {
if reflect.TypeOf(v1).Kind() == reflect.Map { if reflect.TypeOf(v1).Kind() == reflect.Map {
for k2, v2 := range v1.(map[string]interface{}) { for k2, v2 := range v1.(M) {
configMap[k2] = v2 configMap[k2] = v2
} }
} else { } else {

View File

@ -38,6 +38,14 @@ import (
"github.com/astaxie/beego/utils" "github.com/astaxie/beego/utils"
) )
//commonly used mime-types
const (
ApplicationJSON = "application/json"
ApplicationXML = "application/xml"
ApplicationYAML = "application/x-yaml"
TextXML = "text/xml"
)
// NewContext return the Context with Input and Output // NewContext return the Context with Input and Output
func NewContext() *Context { func NewContext() *Context {
return &Context{ return &Context{

View File

@ -260,6 +260,19 @@ func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
return output.Body(content) return output.Body(content)
} }
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
accept := output.Context.Input.Header("Accept")
switch accept {
case ApplicationYAML:
output.YAML(data)
case ApplicationXML, TextXML:
output.XML(data, hasIndent)
default:
output.JSON(data, hasIndent, len(hasEncode) > 0 && hasEncode[0])
}
}
// Download forces response for download file. // Download forces response for download file.
// it prepares the download response header automatically. // it prepares the download response header automatically.
func (output *BeegoOutput) Download(file string, filename ...string) { func (output *BeegoOutput) Download(file string, filename ...string) {

View File

@ -32,14 +32,6 @@ import (
"github.com/astaxie/beego/session" "github.com/astaxie/beego/session"
) )
//commonly used mime-types
const (
applicationJSON = "application/json"
applicationXML = "application/xml"
applicationYAML = "application/x-yaml"
textXML = "text/xml"
)
var ( var (
// ErrAbort custom error when user stop request handler manually. // ErrAbort custom error when user stop request handler manually.
ErrAbort = errors.New("User stop run") ErrAbort = errors.New("User stop run")
@ -281,9 +273,9 @@ func (c *Controller) Redirect(url string, code int) {
func (c *Controller) SetData(data interface{}) { func (c *Controller) SetData(data interface{}) {
accept := c.Ctx.Input.Header("Accept") accept := c.Ctx.Input.Header("Accept")
switch accept { switch accept {
case applicationJSON: case context.ApplicationYAML:
c.Data["json"] = data c.Data["yaml"] = data
case applicationXML, textXML: case context.ApplicationXML, context.TextXML:
c.Data["xml"] = data c.Data["xml"] = data
default: default:
c.Data["json"] = data c.Data["json"] = data
@ -332,33 +324,22 @@ func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
// ServeJSON sends a json response with encoding charset. // ServeJSON sends a json response with encoding charset.
func (c *Controller) ServeJSON(encoding ...bool) { func (c *Controller) ServeJSON(encoding ...bool) {
var ( var (
hasIndent = true hasIndent = BConfig.RunMode != PROD
hasEncoding = false hasEncoding = len(encoding) > 0 && encoding[0]
) )
if BConfig.RunMode == PROD {
hasIndent = false
}
if len(encoding) > 0 && encoding[0] {
hasEncoding = true
}
c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding) c.Ctx.Output.JSON(c.Data["json"], hasIndent, hasEncoding)
} }
// ServeJSONP sends a jsonp response. // ServeJSONP sends a jsonp response.
func (c *Controller) ServeJSONP() { func (c *Controller) ServeJSONP() {
hasIndent := true hasIndent := BConfig.RunMode != PROD
if BConfig.RunMode == PROD {
hasIndent = false
}
c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent) c.Ctx.Output.JSONP(c.Data["jsonp"], hasIndent)
} }
// ServeXML sends xml response. // ServeXML sends xml response.
func (c *Controller) ServeXML() { func (c *Controller) ServeXML() {
hasIndent := true hasIndent := BConfig.RunMode != PROD
if BConfig.RunMode == PROD {
hasIndent = false
}
c.Ctx.Output.XML(c.Data["xml"], hasIndent) c.Ctx.Output.XML(c.Data["xml"], hasIndent)
} }
@ -367,19 +348,11 @@ func (c *Controller) ServeYAML() {
c.Ctx.Output.YAML(c.Data["yaml"]) c.Ctx.Output.YAML(c.Data["yaml"])
} }
// ServeFormatted serve Xml OR Json, depending on the value of the Accept header // ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
func (c *Controller) ServeFormatted() { func (c *Controller) ServeFormatted(encoding ...bool) {
accept := c.Ctx.Input.Header("Accept") hasIndent := BConfig.RunMode != PROD
switch accept { hasEncoding := len(encoding) > 0 && encoding[0]
case applicationJSON: c.Ctx.Output.ServeFormatted(c.Data, hasIndent, hasEncoding)
c.ServeJSON()
case applicationXML, textXML:
c.ServeXML()
case applicationYAML:
c.ServeYAML()
default:
c.ServeJSON()
}
} }
// Input returns the input data map from POST or PUT request body and query string. // Input returns the input data map from POST or PUT request body and query string.

View File

@ -361,7 +361,7 @@ func gatewayTimeout(rw http.ResponseWriter, r *http.Request) {
func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errContent string) { func responseError(rw http.ResponseWriter, r *http.Request, errCode int, errContent string) {
t, _ := template.New("beegoerrortemp").Parse(errtpl) t, _ := template.New("beegoerrortemp").Parse(errtpl)
data := map[string]interface{}{ data := M{
"Title": http.StatusText(errCode), "Title": http.StatusText(errCode),
"BeegoVersion": VERSION, "BeegoVersion": VERSION,
"Content": template.HTML(errContent), "Content": template.HTML(errContent),

View File

@ -692,7 +692,7 @@ func ge(arg1, arg2 interface{}) (bool, error) {
// MapGet getting value from map by keys // MapGet getting value from map by keys
// usage: // usage:
// Data["m"] = map[string]interface{} { // Data["m"] = M{
// "a": 1, // "a": 1,
// "1": map[string]float64{ // "1": map[string]float64{
// "c": 4, // "c": 4,

View File

@ -329,7 +329,7 @@ func TestMapGet(t *testing.T) {
} }
// test 2 level map // test 2 level map
m2 := map[string]interface{}{ m2 := M{
"1": map[string]float64{ "1": map[string]float64{
"2": 3.5, "2": 3.5,
}, },
@ -344,11 +344,11 @@ func TestMapGet(t *testing.T) {
} }
// test 5 level map // test 5 level map
m5 := map[string]interface{}{ m5 := M{
"1": map[string]interface{}{ "1": M{
"2": map[string]interface{}{ "2": M{
"3": map[string]interface{}{ "3": M{
"4": map[string]interface{}{ "4": M{
"5": 1.2, "5": 1.2,
}, },
}, },