Golang使用Swagger时无法读取HTTP请求的解决方法

Golang使用Swagger时无法读取HTTP请求的解决方法 我使用 Swagger API-codegen 创建了 Swagger API 定义文件。然而,当我尝试传递请求时遇到了错误。有人能告诉我哪里出错了吗?以及如何读取数据?

package main

import (
	"flag"
	"fmt"
	"os"

	api "newform-api/inputform"

	"github.com/deepmap/oapi-codegen/pkg/middleware"
	"github.com/labstack/echo/v4"
	echomiddleware "github.com/labstack/echo/v4/middleware"
)

// ServerInterface represents all server handlers.
type ServerInterface interface {
	Externalhealthcheck(ctx echo.Context) error
	NewFormEntry(ctx echo.Context) error
}

func main() {
	var port = flag.Int("port", 8080, "Port for test HTTP server")
	flag.Parse()

	swagger, err := api.GetSwagger()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
		os.Exit(1)
	}

	swagger.Servers = nil

	apiData := api.ServerInterfaceWrapper{}

	e := echo.New()
	e.Use(echomiddleware.Logger())

	e.Use(middleware.OapiRequestValidator(swagger))

	api.RegisterHandlers(e, apiData.Handler)
	e.Logger.Fatal(e.Start(fmt.Sprintf("0.0.0.0:%d", *port)))
}

我遇到了以下错误:

echo: http: panic serving [::1]:61803: runtime error: invalid memory address or nil pointer dereference
goroutine 21 [running]:
net/http.(*conn).serve.func1(0xc0000b21e0)
	/usr/local/go/src/net/http/server.go:1801 +0x147
panic(0x14f7460, 0x18bed00)
	/usr/local/go/src/runtime/panic.go:975 +0x47a
newform-api/inputform.(*ServerInterfaceWrapper).Externalhealthcheck(...)

API 定义文件:

github.com

api-descriptions/inputform at main · Nosh786/api-descriptions

main/inputform

Contribute to Nosh786/api-descriptions development by creating an account on GitHub.


更多关于Golang使用Swagger时无法读取HTTP请求的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang使用Swagger时无法读取HTTP请求的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


从错误信息看,这是一个空指针解引用问题。问题出现在 ServerInterfaceWrapper 的实现上。你创建了 api.ServerInterfaceWrapper{} 但没有提供具体的实现,导致调用处理器时出现空指针。

以下是修复后的代码:

package main

import (
	"flag"
	"fmt"
	"os"

	api "newform-api/inputform"

	"github.com/deepmap/oapi-codegen/pkg/middleware"
	"github.com/labstack/echo/v4"
	echomiddleware "github.com/labstack/echo/v4/middleware"
)

// 实现 ServerInterface 接口
type ServerImpl struct{}

func (s *ServerImpl) Externalhealthcheck(ctx echo.Context) error {
	return ctx.JSON(200, map[string]string{"status": "ok"})
}

func (s *ServerImpl) NewFormEntry(ctx echo.Context) error {
	// 读取请求体
	var requestBody map[string]interface{}
	if err := ctx.Bind(&requestBody); err != nil {
		return ctx.JSON(400, map[string]string{"error": "invalid request"})
	}
	
	// 处理请求数据
	fmt.Printf("Received form data: %v\n", requestBody)
	
	return ctx.JSON(200, map[string]interface{}{
		"success": true,
		"data":    requestBody,
	})
}

func main() {
	var port = flag.Int("port", 8080, "Port for test HTTP server")
	flag.Parse()

	swagger, err := api.GetSwagger()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
		os.Exit(1)
	}

	swagger.Servers = nil

	// 使用具体的实现
	serverImpl := &ServerImpl{}
	apiData := api.ServerInterfaceWrapper{
		Handler: serverImpl,
	}

	e := echo.New()
	e.Use(echomiddleware.Logger())
	e.Use(middleware.OapiRequestValidator(swagger))

	api.RegisterHandlers(e, apiData.Handler)
	e.Logger.Fatal(e.Start(fmt.Sprintf("0.0.0.0:%d", *port)))
}

对于读取HTTP请求数据,在 NewFormEntry 方法中,使用 ctx.Bind() 来解析请求体。如果需要读取特定类型的请求,可以定义对应的结构体:

type FormEntryRequest struct {
	Name    string `json:"name"`
	Email   string `json:"email"`
	Message string `json:"message"`
}

func (s *ServerImpl) NewFormEntry(ctx echo.Context) error {
	var req FormEntryRequest
	if err := ctx.Bind(&req); err != nil {
		return ctx.JSON(400, map[string]string{"error": "invalid request format"})
	}
	
	// 访问具体字段
	fmt.Printf("Name: %s, Email: %s\n", req.Name, req.Email)
	
	return ctx.JSON(200, map[string]interface{}{
		"success": true,
		"name":    req.Name,
		"email":   req.Email,
	})
}

如果需要读取查询参数,可以使用 ctx.QueryParam()

func (s *ServerImpl) NewFormEntry(ctx echo.Context) error {
	// 读取查询参数
	id := ctx.QueryParam("id")
	page := ctx.QueryParam("page")
	
	// 读取请求体
	var requestBody map[string]interface{}
	if err := ctx.Bind(&requestBody); err != nil {
		return ctx.JSON(400, map[string]string{"error": "invalid request"})
	}
	
	return ctx.JSON(200, map[string]interface{}{
		"id":   id,
		"page": page,
		"data": requestBody,
	})
}

确保你的Swagger定义正确指定了请求体格式(如 application/json),这样 ctx.Bind() 才能正确解析。

回到顶部