Beego Controller.ServeJSON 一次统一返回的封装

By.chen
CreateTime: 2019-12-11
这篇Blog是对学习的一次梳理,如有不同的见解 还望指出

简述

在webService的开发当中,往往会需要一个统一格式的返回结果,这样方便客户端去判断和取值。
最近在学习Golang reflect 以及结合前面学习的知识,这里针对在beego高性能框架。进行一个统一返回值的封装。当然这里还是以学习为主,我并不熟悉beego所以不知道里面有没有现成的方法。

代码

利用结构体匿名继承的特性,我们新建一个去实现一些方法被继承的结构体"父类"
下面结构体实现的方法主要用于方便调用。而不是主要核心代码


package controllers

import (
    "github.com/astaxie/beego"

    "project.1/common/returnMessage"
)

// 继承框架实现的控制器结构体
type BaseController struct {
    beego.Controller
}

/**
 * 还原指针
 */
func (this *BaseController) reflectRetJsonPor() *returnMessage.RetJson{
    res,ok := this.Data["retJsonPor"].(*returnMessage.RetJson)
    if !ok {
        return this.CreateJsonRet()
    }
    return res
}

/**
 * 内容返回 成功
 */
func (this *BaseController) RetJsonSuccess(){
    this.reflectRetJsonPor().ReturnJsonSuccess(this);
}

/**
* 内容返回 失败
*/
func (this *BaseController) RetJsonFail() {
    this.reflectRetJsonPor().ReturnJsonSuccess(this);
}

/*
 * 创建返回结构体
 */
func (this *BaseController) CreateJsonRet() *returnMessage.RetJson{
    this.Data["retJsonPor"] = returnMessage.NewRetJson()
    return this.reflectRetJsonPor()
}

/**
 * SetRetJsonPor
 * 设置返回数据指针
 */
func (this *BaseController) SetRetJsonPor(RetJsonPorSon *returnMessage.RetJson){
    this.Data["retJsonPor"] = RetJsonPorSon
}

/**
 * GetRetJsonPor
 * 获取返回数据指针
 */
func (this *BaseController) GetRetJsonPor()(*returnMessage.RetJson){
    return this.reflectRetJsonPor()
}

核心代码

package returnMessage

import (
    "project.1/common/enum"
    "reflect"
)

type RetJson struct {
    // 状态码
    Code int32 `json:"code"`
    // 返回信息
    Msg string `json:"msg"`
    // 返回数据
    Data map[string]interface{} `json:"data"`
}

/**
 * 创建返回结构体
 */
func NewRetJson() *RetJson{
    var newRetJson = RetJson{
        Code:0,
        Msg:"",
        Data:make(map[string]interface{}),
    }
    return &newRetJson
}

/**
 * 提供链式操作方式
 * 设置信息
 */
func (this *RetJson) SetMsg(msg string) *RetJson {
    this.Msg = msg
    return this
}

/**
 * 提供链式操作方式
 * 设置Data
 */
func (this *RetJson) SetData(mapData map[string]interface{}) *RetJson {
    this.Data = mapData
    return this
}

/**
 * SUCCESS 成功请求
 */
func (this *RetJson) ReturnJsonSuccess(BaseInterface interface{}){
    if this.Code == 0    {
        this.Code = enum.HttpCodeSuccess  ;
    }
    if this.Msg == "" {
        this.Msg = "请求执行成功!"
    }
    // 发送
    sendResponse(this,BaseInterface)
}

/**
 * FAIL 失败请求
 */
func (this *RetJson) ReturnJsonFail(BaseInterface interface{}){
    if this.Code == 0    {
        this.Code = enum.HttpCodeFailure
    }
    if this.Msg == "" {
        this.Msg = "请求执行失败!"
    }
    // 发送
    sendResponse(this,BaseInterface)
}

/**
 * SENDResponse 发送响应
 */
func sendResponse (this *RetJson,BaseInterface interface{}){
    // 获取反射的包
    rVal := reflect.ValueOf(BaseInterface)
    rElem := rVal.Elem()
    // 给控制器 data变量赋值
    rElem.FieldByName("Data").SetMapIndex(reflect.ValueOf("json"),reflect.ValueOf(this).Elem())
    // 输出
    action := rVal.MethodByName("ServeJSON")
    //定义参数
    action.Call([]reflect.Value{});
}

方法定义部分结束


调用

// 控制器继承
// routes
beego.Router("/regist",&controllers.AuthController{},"post:Regist");
// Controller
type AuthController struct {
    controllers.BaseController
}

// 正常实现一个被调用的方法
func (this *AuthController) Regist() {
    // 可通Controller struct 实例化 RetJson 通过一下调用
    // 链式操作赋值
    this.CreateJsonRet().SetMsg("请求成功1")
    // 获取RetJson实例 直接 赋值
    this.GetRetJsonPor().Msg = "请求成功2"
    // 获取RetJson实例 方法 赋值
    this.GetRetJsonPor().SetMsg("请求成功")
    // 先实例化RetJson 再调用方法
    this.SetRetJsonPor(returnMessage.NewRetJson())
    // ....
    this.RetJsonSuccess();
}

图示

操作示例图


控制器上的操作

返回示意图


返回值