Go-Spring study notes three [v1.1.0 version]

version of record

  • Go-Spring v1.1.0-rc2

Install

# 安装spring核心包
go get -u github.com/go-spring/[email protected]
# 安装web starter
# gin
go get -u github.com/go-spring/[email protected]
# echo
go get -u github.com/go-spring/[email protected]

1. Filter

1.1 Create a web filter

main.go

package main

import (
	"errors"
	"github.com/go-spring/spring-core/gs"
	"github.com/go-spring/spring-core/web"
	// 引入spring web引擎
	// gin
	SpringGin "github.com/go-spring/spring-gin"
	// echo
	//SpringEcho "github.com/go-spring/spring-echo"
	// 这里使用SpringGin方式创建一个web容器, 因此引入web starter而不是具体某个web引擎的starter
	_ "github.com/go-spring/starter-web"
	"log"
)

// 定义token过滤器
type TokenFilter struct {
    
    
}

/**
	设置过滤器指定的path pattern范围, 这里设置为 /test2/* 即拦截 /test2/*类型的端点
	若不定义该方法则默认为全局拦截器
 */
func (f *TokenFilter) URLPatterns() []string {
    
    
	return []string{
    
    "/test2/*"}
}

// 实现 web.Filter 接口
func (t *TokenFilter) Invoke(ctx web.Context, chain web.FilterChain) {
    
    
	token :=  ctx.QueryParam("token")
	if token != "abcde" {
    
    
		ctx.JSON(web.ERROR.Error(errors.New("invalid token")))
	} else {
    
    
		chain.Next(ctx)
	}
}

func init() {
    
    
	// 使用SpringGin创建web容器, 使用该方式可创建多http server
	webContainer := SpringGin.NewContainer(web.ContainerConfig{
    
    
		Port:     8080,
		BasePath: "/",
	})
	// 为web容器添加token过滤器
	webContainer.AddFilter(&TokenFilter{
    
    })
	// 若直接使用默认容器则使用如下方法添加过滤器
	// gs.Object(&TokenFilter{}).Export((*web.Filter)(nil))

	// 注入容器并设置导出接口
	gs.Object(webContainer).Export((*web.Container)(nil))

	/*
		访问 http://127.0.0.1:8080/test/t1 将不会经过token拦截器, 返回:
			{
				"code": 200,
				"msg": "SUCCESS"
			}
		访问 http://127.0.0.1:8080/test2/t1 将被token过滤器拦截, 返回:
			{
				"code": -1,
				"msg": "ERROR",
				"err": "/path/main.go:32: invalid userId"
			}
		访问 http://127.0.0.1:8080/test2/t1?token=abcde 将被token过滤器放行, 返回:
			{
				"code": 200,
				"msg": "SUCCESS"
			}
	*/
	gs.Object(new(testController)).Init(func(c *testController) {
    
    
		gs.GetMapping("/test/t1", c.echo)
		gs.GetMapping("/test2/t1", c.echo)
	})
}

// 定义测试控制器
type testController struct {
    
    
}

func (c *testController) echo(ctx web.Context) {
    
    
	ctx.JSON(web.SUCCESS)
}

func main() {
    
    
	log.Fatal(gs.Run())
}

In the spring-gin v1.1.0-rc2 version, the middleware does not directly intercept and return the result, but returns the result of the interceptor combined with the result returned by the endpoint method. Here, modify the source code file github.com/go-spring/ Lines 168 and 174 of spring-gin/container.go can be solved (the problem has been reported, and there should be no such problem until the official version)

// ...省略
func HandlerWrapper(fn web.Handler, wildCardName string, filters []web.Filter) []gin.HandlerFunc {
    
    
	var handlers []gin.HandlerFunc

	handlers = append(handlers, func(ginCtx *gin.Context) {
    
    
		if WebContext(ginCtx) == nil {
    
    
			NewContext(fn, wildCardName, ginCtx)
		}
	})

	for _, filter := range filters {
    
    
		f := filter
		handlers = append(handlers, func(ginCtx *gin.Context) {
    
    
			f.Invoke(WebContext(ginCtx), &ginFilterChain{
    
    ginCtx})
			ginCtx.Abort() // 168行之后添加该代码
		})
	}

	handlers = append(handlers, func(ginCtx *gin.Context) {
    
    
		fn.Invoke(WebContext(ginCtx))
		ginCtx.Abort() // 174行之后添加该代码
	})

	return handlers
}
// ...省略

1.2 Replace the default web log filter

The web container started by Go-Spring will have a default log filter. When we do not need to use the default log and customize the log, we can reset the log filter when creating the container, as follows:

main.go

package main

import (
	"github.com/go-spring/spring-core/gs"
	"github.com/go-spring/spring-core/web"
	SpringGin "github.com/go-spring/spring-gin"
    // 仅使用starter web
	_ "github.com/go-spring/starter-web"
	"log"
	"time"
)

func init() {
    
    
    // 方式一
	// 创建gin容器, 并设置初始化方法
	gs.Object(SpringGin.NewContainer(web.ContainerConfig{
    
    
		Port: 8080,
		BasePath: "/",
	})).Init(func(container *SpringGin.Container) {
    
    
        // 直接使用内置的web.FuncFilter方法构建过滤器
		container.SetLoggerFilter(web.FuncFilter(func(ctx web.Context, chain web.FilterChain) {
    
    
            // 自定义日志信息
			startTime := time.Now()
			chain.Next(ctx)
			log.Printf("接口耗时:%v", time.Since(startTime))
		}))
        // 导出为web.Container类型(若不指定将无法检测到web容器)
	}).Export((*web.Container)(nil))
    
    // 方式二
    // 使用gs.Provide + 函数方式创建 web 容器, 创建容器过程中配置容器日志过滤器及其他信息
    //gs.Provide(func() web.Container {
    
    
	//	webContainer := SpringGin.NewContainer(web.ContainerConfig{
    
    
	//		Port:     8080,
	//		BasePath: "/",
	//	})
	//	webContainer.SetLoggerFilter(web.FuncFilter(func(ctx web.Context, chain web.FilterChain) {
    
    
	//		startTime := time.Now()
	//		chain.Next(ctx)
	//		log.Printf("接口耗时:%v", time.Since(startTime))
	//	}))
	//	return webContainer
	//})

    
	// 定义GET方法端点
	gs.GetMapping("/", func(ctx web.Context) {
    
    
		ctx.JSON(web.SUCCESS.Data("Hello Go-Spring!"))
	})
}

func main() {
    
    
	log.Fatal(gs.Run())
}

Supongo que te gusta

Origin blog.csdn.net/qq_33129963/article/details/121402740
Recomendado
Clasificación