D:\go\src\go7\demo4\main.go代码解析
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"regexp"
"strconv"
)
// Index 静态执行。
//请求URL是http://127.0.0.1/index
//函数说明:
//我们定义了一组map,map中分别有id name address三个字段
//我们通过/index获取对应map中的数据
func Index(w http.ResponseWriter, r *http.Request) {
//无聊,打印出访问记录
//r.Host:主机地址,
//r.Method:请求方法,
//r.Proto:使用协议,
//r.URL.Path:请求路径
log.Println(r.Host, r.Method, r.Proto, r.URL.Path)
//定义一组map,map中分别有id name address三个字段
map1 := map[string]interface{}{
"id": 101,
"name": "张无忌",
"address": "武当山",
}
//将map进行json编码
bytes, err := json.Marshal(map1)
if err != nil {
log.Panicln(err.Error())
}
//将json数据直接写到前台
write, err := w.Write(bytes)
if err != nil {
log.Panicln(err.Error())
}
//无聊,打印看看大小
log.Println(write)
}
// IndexId 动态执行
//请求URL是http://127.0.0.1/index/102
//函数说明:
//我们定义了一组map切片,每1组map中分别有id name address三个字段
//我们通过/index/101 /index/102 /index/103 /index/104 /index/105分别获取对应map中的数据
func IndexId(w http.ResponseWriter, r *http.Request) {
//无聊,打印出访问记录,
//r.Host:主机地址,
//r.Method:请求方法,
//r.Proto:使用协议,
//r.URL.Path:请求路径
log.Println(r.Host, r.Method, r.Proto, r.URL.Path)
//我们定义了一组map切片,每1组map中分别有id name address三个字段
users := []map[string]interface{}{
{"id": 101, "name": "张无忌", "address": "武当山"},
{"id": 102, "name": "赵敏", "address": "元朝"},
{"id": 103, "name": "周芷若", "address": "峨眉派"},
{"id": 104, "name": "杨逍", "address": "明教"},
{"id": 105, "name": "宋江", "address": "梁山"},
}
//进行这一步的目的是为了使用正则解析请求路径r.URL.Path
//regexp.Compile编译分析一个正则表达式。
//如果成功,返回一个可用于匹配文本的Regexp对象。
compile, err := regexp.Compile(`/index/(\d+)`)
if err != nil {
log.Panicln(err)
}
//无聊,看看请求的路径吧
log.Println(r.URL.Path)
//func (re *Regexp) FindStringSubmatch(s string) []string
//FindStringSubmatch方法将根据Regexp对象匹配s字符串,返回 []string,
match := compile.FindStringSubmatch(r.URL.Path)
//打印看看匹配上了没,如果匹配上了,看下长度,0是自身,1开始是匹配
log.Println(match, len(match))
//判断下长度大于0,那么就是匹配上了
if len(match) > 0 {
//取出url匹配到的\d+
id := match[1]
//看下匹配到的值和类型,可以看到类型是string
log.Println(fmt.Sprintf("value : %v , type: %T", id, id))
//由于map切片中,id的值是int类型,因此需要将匹配到的值进行转换成int类型
intId, err := strconv.Atoi(id)
if err != nil {
log.Panicln(err.Error())
return
}
//循环迭代出map切片,并对id值进行匹配
for _, v := range users {
//如果发现相同id
if v["id"] == intId {
//将相同ID的map值进行json编码
bytes, err := json.Marshal(map[string]interface{}{
"id": v["id"],
"name": v["name"],
"address": v["address"],
})
if err != nil {
log.Panicln(err.Error())
}
//将json信息输出到前台
write, err := w.Write(bytes)
if err != nil {
log.Panicln(err.Error())
}
//没事,就是想看看大小
log.Println(write)
//查询到就可以了,退出循环
return
}
}
} else {
//当然,如果查询不到,那么就返回404错误
w.WriteHeader(http.StatusNotFound)
}
}
func main() {
//设置日志显示特殊要求,
//增加了log.Llongfile,可以显示日志产生的行号,
//方便检查过程,生产环境下,还是去掉这个。
log.SetFlags(log.LstdFlags | log.Llongfile)
//因为http.ListenAndServe("", nil)的第二个参数设置成了nil,那么默认启用了DefaultServeMux
//那么http.HandleFunc函数就是为了给DefaultServeMux注册处理函数,其中第一个参数是匹配路径
http.HandleFunc("/index", Index)
http.HandleFunc("/index/", IndexId)
_ = http.ListenAndServe("", nil)
}
单元测试代码
package main
import (
"io/ioutil"
"net/http"
"net/http/httptest"
"strconv"
"testing"
)
func TestIndex(t *testing.T) {
handler := http.HandlerFunc(Index)
app := httptest.NewServer(handler)
defer app.Close()
url := app.URL + "/index"
t.Log(url)
response, err := http.Get(url)
if err != nil {
t.Log(err.Error())
}
defer response.Body.Close()
bytes, err := ioutil.ReadAll(response.Body)
if err != nil {
t.Log(err.Error())
}
t.Log(string(bytes))
}
func TestIndexId(t *testing.T) {
handler := http.HandlerFunc(IndexId)
app := httptest.NewServer(handler)
defer app.Close()
for i := 101; i < 106; i++ {
url := app.URL + "/index/"+strconv.Itoa(i)
t.Log(url)
response, err := http.Get(url)
if err != nil {
t.Log(err.Error())
}
defer response.Body.Close()
bytes, err := ioutil.ReadAll(response.Body)
if err != nil {
t.Log(err.Error())
}
t.Log(string(bytes))
}
}
单元测试结果
GOROOT=C:\Program Files\Go #gosetup
GOPATH=D:\go #gosetup
"C:\Program Files\Go\bin\go.exe" test -c -o C:\Users\Administrator\Temp\___go7_demo4__TestIndexId.test.exe go7/demo4 #gosetup
"C:\Program Files\Go\bin\go.exe" tool test2json -t C:\Users\Administrator\Temp\___go7_demo4__TestIndexId.test.exe -test.v -test.paniconexit0 -test.run ^\QTestIndexId\E$ #gosetup
=== RUN TestIndexId
main_test.go:36: http://127.0.0.1:55890/index/101
2022/01/07 23:35:06 127.0.0.1:55890 GET HTTP/1.1 /index/101
2022/01/07 23:35:06 /index/101
2022/01/07 23:35:06 [/index/101 101] 2
2022/01/07 23:35:06 value : 101 , type: string
2022/01/07 23:35:06 51
main_test.go:46: {"address":"武当山","id":101,"name":"张无忌"}
main_test.go:36: http://127.0.0.1:55890/index/102
2022/01/07 23:35:06 127.0.0.1:55890 GET HTTP/1.1 /index/102
2022/01/07 23:35:06 /index/102
2022/01/07 23:35:06 [/index/102 102] 2
2022/01/07 23:35:06 value : 102 , type: string
2022/01/07 23:35:06 45
main_test.go:46: {"address":"元朝","id":102,"name":"赵敏"}
main_test.go:36: http://127.0.0.1:55890/index/103
2022/01/07 23:35:06 127.0.0.1:55890 GET HTTP/1.1 /index/103
2022/01/07 23:35:06 /index/103
2022/01/07 23:35:06 [/index/103 103] 2
2022/01/07 23:35:06 value : 103 , type: string
2022/01/07 23:35:06 51
main_test.go:46: {"address":"峨眉派","id":103,"name":"周芷若"}
main_test.go:36: http://127.0.0.1:55890/index/104
2022/01/07 23:35:06 127.0.0.1:55890 GET HTTP/1.1 /index/104
2022/01/07 23:35:06 /index/104
2022/01/07 23:35:06 [/index/104 104] 2
2022/01/07 23:35:06 value : 104 , type: string
2022/01/07 23:35:06 45
main_test.go:46: {"address":"明教","id":104,"name":"杨逍"}
main_test.go:36: http://127.0.0.1:55890/index/105
2022/01/07 23:35:06 127.0.0.1:55890 GET HTTP/1.1 /index/105
2022/01/07 23:35:06 /index/105
2022/01/07 23:35:06 [/index/105 105] 2
2022/01/07 23:35:06 value : 105 , type: string
2022/01/07 23:35:06 45
main_test.go:46: {"address":"梁山","id":105,"name":"宋江"}
--- PASS: TestIndexId (0.04s)
PASS
进程 已完成,退出代码为 0
本文暂时没有评论,来添加一个吧(●'◡'●)