go中的http包的学习

本文介绍了Go语言中http包的使用,包括服务端的启动,如HandleFunc绑定路由,ListenAndServe监听端口,以及手动路由绑定的不便。接着探讨了通过实现接口自定义路由的方法,提高代码可读性和维护性。客户端部分讲解了GET和POST请求的发送,特别是POST请求中表单和JSON格式的区别。
摘要由CSDN通过智能技术生成

go中的http包的学习

Go语言通过引入net/http包来实现http网络访问,并提供HTTP客户端和服务端的实现。

http 服务端

先看服务端的实现,几行代码就可以启动1个HTTP服务,还是很简单的。

package main

import (
	"fmt"
	"net/http"
)

func getHandler(w http.ResponseWriter, r *http.Request){
	_, _ = fmt.Fprintf(w, "hello go!")
}

func main(){
	//绑定路由
	http.HandleFunc("/", getHandler)
	//监听端口,开启服务
	err := http.ListenAndServe(":9090", nil)
	if err != nil{
		fmt.Println("ListenAndServe: ", err)
	}
}

简单的分析一下这几行代码的意思。

  1. http.HandleFunc("/", getHandler) 表示绑定路由,URL上 是 / 的请求,都它走 getHandler 方法去执行。
  2. http.ListenAndServe(":9090", nil) 表示的监听本地的9090端口,并启动服务,第二参数handler 为 nil,表示不传,这个在下面进行分析。
  3. getHandler 函数,他接受2个参数,固定写法,一个是给客户端返回的Respone,一个是接受请求的Request。

简单的几句代码,就完成了一个HTTP服务,还是很方便的。

go里面路由是得自己手动进行绑定的,而且是强匹配。你没绑定,就访问不了。所以得1个1个进行绑定,这是很痛苦的一件事情。

//绑定路由
http.HandleFunc("/", getHandler1)
http.HandleFunc("/about", getHandler2)
http.HandleFunc("/user/getUserInfo", getHandler3)
http.HandleFunc("/goods/getList", getHandler4)
......

如果你的项目有很多个接口,那就完蛋了。这样写下去得累死不说,而且很难维护,代码的可读性以及整体感觉会很乱。

最关键是没法实现一些很常见的正则的匹配,比如:

http.HandleFunc("/user/{id}", getHandler4)
http.HandleFunc("/user/{id}/name/{name}", getHandler4)

所以,我想想,怎么去搞一套自动匹配路由的机制,和PHP一样方便。先来看一下,第二种启动服务的方式。

func ListenAndServe(addr string, handler Handler) error {}

ListenAndServe 的第一个参数addr,第二个参数类型是Handler。我们看下Handler的定义:

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

他是一个接口。只要实现了接口里面的ServeHTTP的方法的,都可以传入。我们可以利用这个参数,来实现自动化路由:

package main

import (
	"fmt"
	"net/http"
)

func getHandler(w http.ResponseWriter, r *http.Request){

	if r.URL.Path == "/" {
		_, _ = fmt.Fprintf(w, "hello go!")
		return
	}

	if r.URL.Path == "/about" {
		_, _ = fmt.Fprintf(w, "about go!")
		return
	}

	http.NotFound(w, r)
}

func main(){
	//http.HandleFunc("/b", getHandler)
	err := http.ListenAndServe(":9090", http.HandlerFunc(getHandler))
	if err != nil{
		fmt.Println("ListenAndServe: ", err)
	}
}

差不多的代码,http.HandlerFunc() 是将一个普调的函数转换成Handler类型的。这样,我们就可以在函数里面通过判断r.URL.Path的方式,来实现自动路由了。

但是这一种效率比第一张直接绑定的效率要低一点。

也可以自定义方法,只要实现ServeHTTP就行:

package webser

import (
    "strings"
    "fmt"
    "net/http"
    "log"
)

type MyMux struct{
   
}

func (p *MyMux)ServeHTTP(w http.ResponseWriter, r *http.Request){
   
    if r.URL.Path == "/"{
   
        sayHelloName(w, r)
        return
    }
    if r.URL.Path == "/about"{
   
        about(w, r)
        return
    }
    http.NotFound(w,r)
    return
}

func sayHelloName(w http.ResponseWriter, r *http.Request){
   
    r.ParseForm()
    fmt.Println(r.Form)
    fmt.Println("path: ", r.URL.Path)
    fmt.Println("scheme: ", r.URL.Scheme)
    for k, v := range r.Form{
   
        fmt.Println("key: ", k)
        fmt.Println("val: "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值