如何实现类似继承的效果

在iris的mvc架构中,我有一组XxxController结构体,每个结构体都需要实现一个auth()方法,为了简便,我尝试所有结构体引入一个名为BaseController的结构体,这样我就可以在各个XxxController里使用这个方法了,代码如下:

//BaseController 根结构体
type BaseController struct {
    Ctx iris.Context
    UserClaims middleware.UserClaims
}

func (b *BaseController) auth() middleware.UserClaims {
    if b.UserClaims.ID > 0 {
        return b.UserClaims
    }
    mc := b.Ctx.Values().Get("jwt").(*jwt.Token).Claims.(jwt.MapClaims)
    return middleware.UserClaims{
        Nickname:  mc["nickname"].(string),
        ID:        uint(mc["id"].(float64)),
        Issuer:    mc["iss"].(string),
        IssuedAt:  int64(mc["iat"].(float64)),
        JwtId:     mc["jti"].(string),
        NotBefore: int64(mc["nbf"].(float64)),
        ExpiresAt: int64(mc["exp"].(float64)),
    }
}


//TestController 子结构体
type TestController struct {
   BaseController
  Service *services.TestService
}

func NewTestController() *TestController {
   return &TestController{Service: services.NewTestService()}
}

func (t *TestController) PostSave() (r models.Result) {
   fmt.Println("PostSave")
   var test models.Test
   if err := t.Ctx.ReadJSON(&test); err != nil {
      t.Ctx.StopWithError(iris.StatusBadRequest, err)
      return models.Result{
         Code: models.CodeFail,
         Msg:  "fail",
      }
   }
   r.Data=test
   r.Auth=t.auth()//直接在子结构体里调用父结构体的方法
   return 
}

我以为这样调用是可行的,但事实上请求会返回一个400错误,返回内容如下:

readObjectStart: expect { or n, but found ▯ , error found in #0 byte of ...||..., bigger context ...||...

是否有大神知道这种情况怎么解

2021年10月27日10点03分:新进展
我发现iris的配置里DisableBodyConsumptionOnUnmarshal设置为true后我上面的模式也可以实现,这个配置百度翻译是:如果此字段设置为true,则将创建一个新的缓冲区来读取和请求正文。不会更改正文,并且不会使用context.UnmarshalBody/ReadJSON/ReadXML之前的现有数据,依然感谢各位大神的指点,‘@滚球兽进化’的方案仍旧是极好的

世界最好语言的追随者
最佳答案

iris 应该有中间件。 或者你自己去丰富这个请求的生命周期。你的需求是在每个控制器的逻辑执行前执行指定逻辑。其实就是 1 -> {} -> 逻辑 -> end 。你从这个角度看的话,实现的方法就多种多样了。我用gin写的时候因为觉得用 context 上设置 user 不太好,就写了个函数把传递过去的控制器方法处理成高阶函数,然后把控制器改造成想要的 request 参数

2年前 评论
renxiaotu (楼主) 2年前
滚球兽进化 (作者) 2年前
renxiaotu (楼主) 2年前
讨论数量: 8

iris 应该有中间件。 或者你自己去丰富这个请求的生命周期。你的需求是在每个控制器的逻辑执行前执行指定逻辑。其实就是 1 -> {} -> 逻辑 -> end 。你从这个角度看的话,实现的方法就多种多样了。我用gin写的时候因为觉得用 context 上设置 user 不太好,就写了个函数把传递过去的控制器方法处理成高阶函数,然后把控制器改造成想要的 request 参数

2年前 评论
renxiaotu (楼主) 2年前
滚球兽进化 (作者) 2年前
renxiaotu (楼主) 2年前

你说的这个报错,从给的来看看不出来是哪的问题

2年前 评论
renxiaotu (楼主) 2年前
2年前 评论
renxiaotu (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!