编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

golang从入门到精通,Web编程,URL路由实现动态查询

wxchong 2024-07-25 13:32:39 开源技术 21 ℃ 0 评论

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

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表