1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. )
  7. func IndexHandle(w http.ResponseWriter,r *http.Request){
  8. fmt.Fprintf(w,"path = %s\n",r.URL.Path)
  9. }
  10. func HelloHandle(w http.ResponseWriter,r *http.Request){
  11. fmt.Fprintf(w,"%v\n",r.Header)
  12. }
  13. func main() {
  14. http.HandleFunc("/",IndexHandle)
  15. http.HandleFunc("/hello",HelloHandle)
  16. log.Fatal(http.ListenAndServe(":8090",nil))
  17. }

//hello,分别绑定 indexHandlerhelloHandler , 根据不同的HTTP请求会调用不同的处理函数。

  1. ListenAndServe(addr string, handler Handler)

:8090表示在 8090 端口监听。而第二个参数是则代表处理所有的HTTP请求的实例,nil 代表使用标准库中的实例处理。

http.Handler

是一个接口

  1. type Handler interface {
  2. ServeHTTP(ResponseWriter, *Request)
  3. }

上面的代码可以如下实现

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. )
  7. type Engine struct {}
  8. func (engine *Engine)ServeHTTP(w http.ResponseWriter, req *http.Request){
  9. switch req.URL.Path {
  10. case "/":
  11. fmt.Fprintf(w,"path = %s\n",req.URL.Path)
  12. case "/hello":
  13. fmt.Fprintf(w,"%v\n",req.Header)
  14. default:
  15. fmt.Fprintf(w,"404 NOT FOUND %s\n",req.URL.Path)
  16. }
  17. }
  18. func main() {
  19. log.Fatal(http.ListenAndServe(":8090",&Engine{}))
  20. }

实现一个简单的路由

  1. package gun
  2. import (
  3. "fmt"
  4. "net/http"
  5. )
  6. type Engine struct {
  7. router map[string] http.HandlerFunc
  8. }
  9. func New()*Engine{
  10. return &Engine{router: map[string]http.HandlerFunc{}}
  11. }
  12. func (engine *Engine)ServeHTTP(w http.ResponseWriter,r *http.Request){
  13. key := r.Method+"-"+r.URL.Path
  14. if handle,ok:=engine.router[key];ok{
  15. handle(w,r)
  16. }else {
  17. fmt.Fprintf(w, "404 NOT FOUND: %s\n", r.URL.Path)
  18. }
  19. }
  20. func(engine *Engine)addRoute(method,path string, handler http.HandlerFunc){
  21. key := method+"-"+path
  22. engine.router[key]= handler
  23. }
  24. func(engine *Engine)Get(path string, handler http.HandlerFunc){
  25. engine.addRoute("GET",path,handler)
  26. }
  27. func(engine *Engine)Post(path string, handler http.HandlerFunc){
  28. engine.addRoute("POST",path,handler)
  29. }
  30. func (engine *Engine)Run(addr string)error{
  31. return http.ListenAndServe(addr,engine)
  32. }

将上面的代码可以改成

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/baxiang/go-note/http/gun"
  5. "net/http"
  6. )
  7. func IndexHandle(w http.ResponseWriter,r *http.Request){
  8. fmt.Fprintf(w,"path = %s\n",r.URL.Path)
  9. }
  10. func HelloHandle(w http.ResponseWriter,r *http.Request){
  11. fmt.Fprintf(w,"%v\n",r.Header)
  12. }
  13. func main() {
  14. r := gun.New()
  15. r.Get("/",IndexHandle)
  16. r.Get("/hello",HelloHandle)
  17. r.Run(":8090")
  18. }

json

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/baxiang/go-note/http/gun"
  6. "net/http"
  7. )
  8. func IndexHandle(w http.ResponseWriter,r *http.Request){
  9. fmt.Fprintf(w,"path = %s\n",r.URL.Path)
  10. }
  11. func HelloHandle(w http.ResponseWriter,r *http.Request){
  12. w.Header().Set("Content-Type","application/json")
  13. w.WriteHeader(http.StatusOK)
  14. encoder := json.NewEncoder(w)
  15. if err :=encoder.Encode(map[string]interface{}{"hello":"world"});err!=nil{
  16. http.Error(w,err.Error(),http.StatusInternalServerError)
  17. }
  18. }
  19. func main() {
  20. r := gun.New()
  21. r.Get("/",IndexHandle)
  22. r.Get("/hello",HelloHandle)
  23. r.Run(":8090")
  24. }


Context

请求上下文的封装

  1. package gun
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "fmt"
  6. )
  7. type H map[string]interface{}
  8. type Context struct {
  9. Writer http.ResponseWriter
  10. Req *http.Request
  11. Path string
  12. Method string
  13. StatusCode int
  14. }
  15. func NewContext(w http.ResponseWriter,req *http.Request)*Context{
  16. return &Context{
  17. Writer: w,
  18. Req: req,
  19. Path: req.URL.Path,
  20. Method: req.Method,
  21. }
  22. }
  23. func(c *Context)SetHeader(key,value string){
  24. c.Writer.Header().Set(key,value)
  25. }
  26. func (c *Context)SetStatusCode(statusCode int){
  27. c.StatusCode = statusCode
  28. c.Writer.WriteHeader(statusCode)
  29. }
  30. func(c *Context)JSON(statusCode int,obj interface{}){
  31. c.SetHeader("Content-Type","application/json")
  32. c.SetStatusCode(statusCode)
  33. encoder := json.NewEncoder(c.Writer)
  34. if err :=encoder.Encode(obj);err!=nil{
  35. http.Error(c.Writer, err.Error(), http.StatusInternalServerError)
  36. }
  37. }
  38. func (c *Context) String(statusCode int, format string, values ...interface{}) {
  39. c.SetHeader("Content-Type", "text/plain")
  40. c.SetStatusCode(statusCode)
  41. c.Writer.Write([]byte(fmt.Sprintf(format, values...)))
  42. }
  43. func (c *Context) HTML(SetStatusCode int, html string) {
  44. c.SetHeader("Content-Type", "text/html")
  45. c.SetStatusCode(SetStatusCode)
  46. c.Writer.Write([]byte(html))
  47. }

router

路由处理逻辑

  1. package gun
  2. import "net/http"
  3. type router struct {
  4. handlers map[string] HandlerFunc
  5. }
  6. func newRouter()*router{
  7. return &router{
  8. handlers: map[string]HandlerFunc{},
  9. }
  10. }
  11. func(r *router)addRouter(method,path string,handle HandlerFunc){
  12. key :=method+"-"+path
  13. r.handlers[key] = handle
  14. }
  15. func(r *router)handle(c *Context){
  16. key :=c.Method+"-"+c.Path
  17. if handler,ok :=r.handlers[key];ok{
  18. handler(c)
  19. }else {
  20. c.String(http.StatusNotFound, "404 NOT FOUND: %s\n", c.Path)
  21. }
  22. }

engine

  1. package gun
  2. import (
  3. "net/http"
  4. )
  5. type HandlerFunc func(*Context)
  6. type Engine struct {
  7. router *router
  8. }
  9. func New()*Engine{
  10. return &Engine{router: newRouter()}
  11. }
  12. func (engine *Engine)ServeHTTP(w http.ResponseWriter,r *http.Request){
  13. c :=NewContext(w,r)
  14. engine.router.handle(c)
  15. }
  16. func(engine *Engine)addRoute(method,path string, handler HandlerFunc){
  17. engine.router.addRouter(method,path,handler)
  18. }
  19. func(engine *Engine)Get(path string, handler HandlerFunc){
  20. engine.addRoute("GET",path,handler)
  21. }
  22. func(engine *Engine)Post(path string, handler HandlerFunc){
  23. engine.addRoute("POST",path,handler)
  24. }
  25. func (engine *Engine)Run(addr string)error{
  26. return http.ListenAndServe(addr,engine)
  27. }