首页 > 其他分享 >gin-net-http 2

gin-net-http 2

时间:2024-01-20 21:58:23浏览次数:36  
标签:http pattern mux handler func gin net ResponseWriter

目前知道gin是基于net/http进一步封装,来看下net/http是怎样写web的

package main

import (
  "fmt"
  "net/http"
)

func index(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintln(w, "Hello World")
}

func main() {
  http.HandleFunc("/", index)
  http.ListenAndServe(":8080", nil)
}

首先,调用http.HandleFunc("/", index)注册路径处理函数,这里将路径/的处理函数设置为index。处理函数的类型必须是:、

func (http.ResponseWriter, *http.Request)

 其中*http.Request表示 HTTP 请求对象,该对象包含请求的所有信息,如 URL、首部、表单内容、请求的其他内容等。

http.ResponseWriter是一个接口类型:

// net/http/server.go
type ResponseWriter interface {
  Header() Header
  Write([]byte) (int, error)
  WriteHeader(statusCode int)
}

用于向客户端发送响应,实现了ResponseWriter接口的类型显然也实现了io.Writer接口。所以在处理函数index中,可以调用fmt.Fprintln()ResponseWriter写入响应信息。

net/http包中HandleFunc()函数的源码:

// The documentation for ServeMux explains how patterns are matched.
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
	DefaultServeMux.HandleFunc(pattern, handler)
}

接调用了一个名为DefaultServeMux对象的HandleFunc()方法。DefaultServeMuxServeMux类型的实例:


type ServeMux struct {
	mu    sync.RWMutex
	m     map[string]muxEntry
	es    []muxEntry // slice of entries sorted from longest to shortest.
	hosts bool       // whether any patterns contain hostnames
}
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux

像这种提供默认类型实例的用法在 Go 语言的各个库中非常常见,在默认参数就已经足够的场景中使用默认实现很方便ServeMux保存了注册的所有路径和处理函数的对应关系。ServeMux.HandleFunc()方法如下:

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
  mux.Handle(pattern, HandlerFunc(handler))
}

这里将处理函数handler转为HandlerFunc类型,然后调用ServeMux.Handle()方法注册。注意这里的HandlerFunc(handler)是类型转换,而非函数调用,类型HandlerFunc的定义如下:

type HandlerFunc func(ResponseWriter, *Request)

func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
  f(w, r)
}

HandlerFunc实际上是以函数类型func(ResponseWriter, *Request)为底层类型,为HandlerFunc类型定义了方法ServeHTTP

mux.Handle(pattern, HandlerFunc(handler)) 调用了func (mux *ServeMux) Handle(pattern string, handler Handler)

// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
	mux.mu.Lock()
	defer mux.mu.Unlock()
	if _, exist := mux.m[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if mux.m == nil {
		mux.m = make(map[string]muxEntry)
	}
	e := muxEntry{h: handler, pattern: pattern}
	mux.m[pattern] = e
	if pattern[len(pattern)-1] == '/' {
		mux.es = appendSorted(mux.es, e)
	}
	if pattern[0] != '/' {
		mux.hosts = true
	}
}

也就是:

mux.Handle(pattern, HandlerFunc(handler))------>func (mux *ServeMux) Handle(pattern string, handler Handler)

HandlerFunc(handler)------>Handler

type Handler interface {
	ServeHTTP(ResponseWriter, *Request)
}

 

标签:http,pattern,mux,handler,func,gin,net,ResponseWriter
From: https://www.cnblogs.com/codestack/p/17977169

相关文章

  • 云计算-http实时通讯
    短链接请求示例在HTTP/1.0中,默认使用的是短连接。如果需要使用长连接:通过Connection:Keep-alive来实现长连接。浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源,如JavaScript文件、图......
  • AtCoder Beginner Contest 336
    AtCoderBeginnerContest33657秒切A,75秒切B。然后C就卡了,没想到五进制,二分答案加数位DP判断过了。用了半个小时。DE读完题,发现D可做。小推了一下发现可以维护线段树。很快写完过了样例。第一发罚时,\(+1\)和\(-1\)写反了。第二发罚时,把那个“金字塔”写成了......
  • gin-net-http
    packagemainimport( "net/http" "github.com/gin-gonic/gin")funcmain(){ r:=gin.Default() r.GET("/",func(c*gin.Context){ c.String(200,"Hello!!!!") })}  gin框架使用的是定制版本的httprouter,其路由的原理是大量使用公共前缀的树结构......
  • [译] kubernetes:kube-scheduler 调度器代码结构概述
    本文翻译自https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduling_code_hierarchy_overview.md译者:胡云Troy调度器代码层次结构概述介绍调度器监视新创建的还没有分配节点的Pod。当发现这样的Pod后,调度器将Pod调度到最......
  • 前后端都用得上的 Nginx 日常使用经验-补充篇
    之前分享了前后端都用得上的Nginx日常使用经验,在配置elk的时候增加了nginxbasicauth和IP百名的配置,作为补充分享。配置nginx域名转发常规的转发配置,不需要https部分去掉即可,一般只需要修改域名和转发地址server{listen80;listen443ssl;s......
  • node-sass 安装出错 Cannot download "https://github.com/sass/node-sass...
    Downloadingbinaryfromhttps://github.com/sass/node-sass/releases/download/v4.14.1/win32-x64-83_binding.nodeCannotdownload"https://github.com/sass/node-sass/releases/download/v4.14.1/win32-x64-83_binding.node": github网站大多时候都访问不到,下载 win32-x......
  • 人人都会Kubernetes(二):使用KRM实现快速部署服务,并且通过域名发布
    1.上节回顾上一小节《人人都会Kubernetes(一):告别手写K8syaml,运维效率提升500%》介绍了KRM的一些常用功能,并且使用KRM的DEMO环境,无需安装就可以很方便的生成一些资源的YAML数据并使用。本节将实现在自己的集群中安装KRM,并且使用KRM去管理分布在各个地方的K8s集群,同时将实现快速......
  • dotnet 多数据库 sqlite efcore model和entity区别 一对多 多对一 多对多
    efcore-multi-db/MultiDb.slnMicrosoftVisualStudioSolutionFile,FormatVersion12.00#VisualStudio15VisualStudioVersion=15.0.27130.2024MinimumVisualStudioVersion=10.0.40219.1Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}")="......
  • vscode netcore运行配置
    launch.json{  "version":"0.2.0",  "configurations":[   {    "name":".NETCoreLaunch(web)",    "type":"coreclr",    "request":"launch&qu......
  • dotnet efcore 多数据库 使用
    efcore的使用依赖包efcore-multi-db/MultiDb.Two/MultiDb.Two.csproj<ProjectSdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net7.0</TargetFramework></PropertyGroup><ItemGroup><Packa......