go-echo学习笔记

go-echo学习笔记,包含了请求与响应,路由,参数解析,模版渲染,登录验证,日志,文件上传与下载,websocket通信。

文章目录

  • [Part1 Get与Post](#Part1 Get与Post)
  • [Part2 四种请求](#Part2 四种请求)
  • [Part3 提取参数](#Part3 提取参数)
  • [Part4 解析json与xml](#Part4 解析json与xml)
  • [Part5 json传输](#Part5 json传输)
  • [Part6 模版渲染](#Part6 模版渲染)
  • [Part7 模版参数传递](#Part7 模版参数传递)
  • [Part8 Cookie与Session](#Part8 Cookie与Session)
  • [Part9 JWT](#Part9 JWT)
  • [Part9 日志](#Part9 日志)
  • [Part10 文件上传与下载](#Part10 文件上传与下载)
  • [Part 11 Websocket通信](#Part 11 Websocket通信)

Part1 Get与Post

主要内容包括登录网页,发送请求并进行处理

go 复制代码
import (
	"github.com/labstack/echo"
	"net/http"
)

func main01() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "<h1>Hello, World</h1>")
	})

	e.Logger.Fatal(e.Start(":1323"))
}

Part2 四种请求

包含了PUT,DELETE PUT与GET,测试的时候需要结合Postman,其中请求时,静态路由要大于参数路由大于匹配路由。

go 复制代码
import (
	"github.com/labstack/echo"
	"net/http"
)

func HelloFunc(c echo.Context) error {
	return c.String(http.StatusOK, "Hello, World!")
}

func UserHandler(c echo.Context) error {
	return c.String(http.StatusOK, "UserHandler")
}

func CreateProduct(c echo.Context) error {
	return c.String(http.StatusOK, "CreateProduct")
}
func FindProduct(c echo.Context) error {
	return c.String(http.StatusOK, "FindProduct")
}
func UpdateProduct(c echo.Context) error {
	return c.String(http.StatusOK, "UpdateProduct")
}
func DeleteProduct(c echo.Context) error {
	return c.String(http.StatusOK, "DeleteProduct")
}

// 静态 > 参数 > 匹配路由
func main() {
	e := echo.New()
	e.GET("/", HelloFunc)
	r := e.Group("/api")
	r.GET("/user", UserHandler)
	//r.GET("/score", ScoreHandler)
	r.POST("/user", CreateProduct)
	r.DELETE("/user", DeleteProduct)
	r.PUT("/user", UpdateProduct)
	e.Logger.Fatal(e.Start(":1325"))
	e.GET("/product/1/price/*", func(c echo.Context) error {
		return c.String(http.StatusOK, "Product 1 price all")
	})
	e.GET("/product/:id", func(c echo.Context) error {
		return c.String(http.StatusOK, "Product "+c.Param("id"))
	})
	e.GET("/product/new", func(c echo.Context) error {
		return c.String(http.StatusOK, "Product new")

	})

}

Part3 提取参数

在接收网页端的请求时,要对请求进行解析。如何解析是这个part的内容,表单发送过来的请求,REST请求,普通带问候的请求方式

go 复制代码
package main

import (
	"github.com/labstack/echo"
	"net/http"
)

func MyHandler(c echo.Context) error {
	p := new(Product)
	if err := c.Bind(p); err != nil {
		return c.String(http.StatusBadRequest, "bad request")
	}
	return c.JSON(http.StatusOK, p)
}

func MyHandler2(c echo.Context) error {
	name := c.FormValue("name")
	return c.String(http.StatusOK, name)
}

func MyHandler3(c echo.Context) error {
	name := c.QueryParam("name")
	return c.String(http.StatusOK, name)
}

func MyHandler4(c echo.Context) error {
	name := c.Param("name")
	return c.String(http.StatusOK, name)
}

type Product struct {
	Name  string `json:"name" form:"name" query:"name"`
	Price int    `json:"price" form:"price" query:"price"`
}

func main() {
	e := echo.New()
	e.GET("/products", MyHandler)
	//在postman 中formdata进行请求
	e.GET("/products2", MyHandler2)
	//与products类似
	e.GET("/products3", MyHandler3)
	e.GET("/products4/:name", MyHandler4)
	e.Logger.Fatal(e.Start(":1328"))
}

Part4 解析json与xml

本part对json传输进行了详细的demo样例,json较为常用。

go 复制代码
import (
	"encoding/json"
	"github.com/labstack/echo"
	"net/http"
)

type Product struct {
	Name  string `json:"name" form:"name" query:"name"`
	Price int    `json:"price" form:"price" query:"price"`
}

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	e.GET("/html", func(c echo.Context) error {
		return c.HTML(http.StatusOK, "<h1>Hello, World!</h1>")
	})
	e.GET("/json", func(c echo.Context) error {
		p := &Product{
			Name:  "football",
			Price: 1000,
		}
		return c.JSON(http.StatusOK, p)
	})
	e.GET("/prettyjson", func(c echo.Context) error {
		p := &Product{
			Name:  "soccer",
			Price: 1000,
		}
		return c.JSONPretty(http.StatusOK, p, "  ")
	})
	e.GET("/streamjson", func(c echo.Context) error {
		p := &Product{
			Name:  "soccer",
			Price: 134,
		}
		c.Response().Header().Set("Content-Type", echo.MIMEApplicationXMLCharsetUTF8)
		c.Response().WriteHeader(http.StatusOK)
		return json.NewEncoder(c.Response()).Encode(p)
	})
	e.GET("/jsonblob", func(c echo.Context) error {
		p := &Product{
			Name:  "volley",
			Price: 120,
		}
		data, _ := json.Marshal(p)
		return c.JSONPBlob(http.StatusOK, "", data)
	})
	e.GET("/xml", func(c echo.Context) error {
		p := &Product{
			Name:  "basketball",
			Price: 120,
		}
		return c.XML(http.StatusOK, p)
	})
	e.GET("/png", func(c echo.Context) error {
		//return c.File("./public/left.png")
		return c.File("./public/test.html")
	})
	e.GET("blub", func(c echo.Context) error {
		data := []byte(`0306703,0035866,NO_ACTION,06/19/2006`)
		return c.Blob(http.StatusOK, "text/csv", data)
	})
	e.GET("null", func(c echo.Context) error {
		return c.NoContent(http.StatusOK)
	})
	e.Logger.Fatal(e.Start(":1330"))
}

Part5 json传输

go 复制代码
package main

import (
	"encoding/json"
	"github.com/labstack/echo"
	"net/http"
)

type Product struct {
	Name  string `json:"name" form:"name" query:"name"`
	Price int    `json:"price" form:"price" query:"price"`
}

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	e.GET("/html", func(c echo.Context) error {
		return c.HTML(http.StatusOK, "<h1>Hello, World!</h1>")
	})
	e.GET("/json", func(c echo.Context) error {
		p := &Product{
			Name:  "football",
			Price: 1000,
		}
		return c.JSON(http.StatusOK, p)
	})
	e.GET("/prettyjson", func(c echo.Context) error {
		p := &Product{
			Name:  "soccer",
			Price: 1000,
		}
		return c.JSONPretty(http.StatusOK, p, "  ")
	})
	e.GET("/streamjson", func(c echo.Context) error {
		p := &Product{
			Name:  "soccer",
			Price: 134,
		}
		c.Response().Header().Set("Content-Type", echo.MIMEApplicationXMLCharsetUTF8)
		c.Response().WriteHeader(http.StatusOK)
		return json.NewEncoder(c.Response()).Encode(p)
	})
	e.GET("/jsonblob", func(c echo.Context) error {
		p := &Product{
			Name:  "volley",
			Price: 120,
		}
		data, _ := json.Marshal(p)
		return c.JSONPBlob(http.StatusOK, "", data)
	})
	e.GET("/xml", func(c echo.Context) error {
		p := &Product{
			Name:  "basketball",
			Price: 120,
		}
		return c.XML(http.StatusOK, p)
	})
	e.GET("/png", func(c echo.Context) error {
		//return c.File("./public/left.png")
		return c.File("./public/test.html")
	})
	e.GET("blub", func(c echo.Context) error {
		data := []byte(`0306703,0035866,NO_ACTION,06/19/2006`)
		return c.Blob(http.StatusOK, "text/csv", data)
	})
	e.GET("null", func(c echo.Context) error {
		return c.NoContent(http.StatusOK)
	})
	e.Logger.Fatal(e.Start(":1330"))
}

Part6 模版渲染

go 复制代码
import (
	"github.com/labstack/echo"
	"net/http"
)

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "Hello, World!")
	})
	e.GET("/index", func(c echo.Context) error {
		return c.File("assets/index.html")
	})
	e.Static("/static", "assets")

	e.Logger.Fatal(e.Start(":9090"))
}

Part7 模版参数传递

go 复制代码
import (
	"github.com/labstack/echo"
	"html/template"
	"io"
	"net/http"
)

type Template struct {
	templates *template.Template
}

func (t *Template) Render(w io.Writer,
	name string, data interface{}, c echo.Context) error {
	return t.templates.ExecuteTemplate(w, name, data)
}
func main() {
	e := echo.New()

	t := &Template{
		templates: template.Must(template.ParseGlob("public/view/*.html")),
	}
	e.Renderer = t
	e.GET("/", func(c echo.Context) error {
		return c.Render(http.StatusOK, "index", "Hello, World!")
	})
	e.GET("/hello", func(c echo.Context) error {
		return c.Render(http.StatusOK, "hello", "World")
	})
	e.Logger.Fatal(e.Start(":1325"))
}

Part8 Cookie与Session

go 复制代码
import (
	"fmt"
	"github.com/gorilla/sessions"
	"github.com/labstack/echo"
	"github.com/labstack/echo-contrib/session"
	"github.com/labstack/echo/v4"
	"net/http"
	"time"
)

func WriteCookie(c echo.Context) error {
	cookie := new(http.Cookie)
	cookie.Name = "userName"
	cookie.Value = "cookieValue"
	cookie.Expires = time.Now().Add(time.Hour * 2)

	c.SetCookie(cookie)
	return c.String(http.StatusOK, "write a cookie")
}

func ReadCookie(c echo.Context) error {
	cookie, err := c.Cookie("userName")
	if err != nil {
		return err
	}
	fmt.Println(cookie.Name)
	fmt.Println(cookie.Value)
	return c.String(http.StatusOK, "read cookie")
}

func ReadAllCookie(c echo.Context) error {
	for _, cookie := range c.Cookies() {
		fmt.Println(cookie.Name)
		fmt.Println(cookie.Value)
	}
	return c.String(http.StatusOK, "read all cookie")
}

func SessionHandler(c echo.Context) error {
	sess, _ := session.Get("session", c)
	sess.Options = &sessions.Options{
		Path:     "/",
		MaxAge:   86400 * 7,
		HttpOnly: true,
	}
	sess.Values["foo"] = "bar"
	sess.Save(c.Request(), c.Response())
	return c.String(http.StatusOK, "session handler")
}
func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "<h1>Hello, World</h1>")
	})

	e.GET("/writeCookie", WriteCookie)
	e.GET("/readCookie", ReadCookie)
	e.GET("/readAllCookie", ReadAllCookie)
	store := sessions.NewCookieStore([]byte("secret"))

	// 使用会话中间件
	e.Use(session.Middleware(store))
	//e.Use(session.Middleware(sessions.NewCookieStore([]byte("secret"))))
	e.GET("/session", SessionHandler)
	e.Logger.Fatal(e.Start(":1325"))
}

Part9 JWT

go 复制代码
import (
	"github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
	"net/http"
	"strconv"
	"time"
)

type User struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

const jwtSecret = "secret"

type JwtCustomClaims struct {
	Name string `json:"name"`
	ID   int    `json:"id"`
	jwt.StandardClaims
}

func Login(c echo.Context) error {

	u := new(User)
	if err := c.Bind(u); err != nil {
		return c.JSON(http.StatusOK, echo.Map{
			"errcode": 401,
			"errmsg":  "request error",
		})
	}
	if "pass" == u.Password && u.Username == "name" {
		claims := &JwtCustomClaims{
			Name: u.Username,
			ID:   12,
			StandardClaims: jwt.StandardClaims{
				ExpiresAt: time.Now().Add(time.Hour * 24).Unix()},
		}

		token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
		t, err := token.SignedString([]byte(jwtSecret))
		if err != nil {
			return err
		}
		return c.JSON(http.StatusOK, echo.Map{
			"token":   t,
			"errcode": 200,
			"errmsg":  "success",
		})
	} else {
		return c.JSON(http.StatusOK, echo.Map{
			"errcode": -1,
			"errmsg":  "failed",
		})
	}
}
func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.String(http.StatusOK, "<h1>Hello, World</h1>")
	})

	e.POST("/login", Login)
	r := e.Group("/api")
	r.Use(middleware.JWTWithConfig(middleware.JWTConfig{
		Claims:     &JwtCustomClaims{},
		SigningKey: []byte(jwtSecret),
	}))

	r.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			user := c.Get("user").(*jwt.Token)
			claims := user.Claims.(*JwtCustomClaims)
			c.Set("name", claims.Name)
			c.Set("uid", claims.ID)
			return next(c)
		}
	})
	r.GET("/getInfo", func(c echo.Context) error {
		name := c.Get("name").(string)
		id := c.Get("id").(int)
		return c.String(http.StatusOK, "name:"+name+"id:"+strconv.Itoa(id))
	})
	e.Logger.Fatal(e.Start(":1323"))
}

Part9 日志

go 复制代码
import (
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
	"github.com/labstack/gommon/log"
	"net/http"
)

func main() {
	e := echo.New()
	e.Use(middleware.Logger())
	e.GET("/", func(c echo.Context) error {
		e.Logger.Debugf("这是格式化输出%s")
		e.Logger.Debugj(log.JSON{"aaa": "cccc"})
		e.Logger.Debug("aaaa")
		return c.String(http.StatusOK, "<h1>Hello, World</h1>")
	})
	e.Logger.SetLevel(log.INFO)
	e.GET("/info", func(c echo.Context) error {
		e.Logger.Infof("这是格式化输出%s")
		e.Logger.Infoj(log.JSON{"aaa": "cccc"})
		e.Logger.Info("aaaa")
		return c.String(http.StatusOK, "INFO PAGE!")
	})
	e.Logger.Fatal(e.Start(":1323"))

}

Part10 文件上传与下载

go 复制代码
import (
	"github.com/labstack/echo"
	"io"
	"net/http"
	"os"
)

func upload(c echo.Context) error {
	file, err := c.FormFile("filename")
	if err != nil {
		return err
	}
	src, err := file.Open()
	if err != nil {
		return err
	}
	defer src.Close()

	dst, err := os.Create("upload/" + file.Filename)
	if err != nil {
		return err
	}
	defer dst.Close()
	if _, err = io.Copy(dst, src); err != nil {
		return err
	}
	return c.String(http.StatusOK, "upload success")
}
func multiUpload(c echo.Context) error {
	form, err := c.MultipartForm()
	if err != nil {
		return err
	}
	files := form.File["files"]

	for _, file := range files {
		src, err := file.Open()
		if err != nil {
			return err
		}
		defer src.Close()

		dst, err := os.Create("upload/" + file.Filename)
		if err != nil {
			return err
		}
		defer dst.Close()
		if _, err = io.Copy(dst, src); err != nil {
			return err
		}
	}
	return c.String(http.StatusOK, "upload success")

}
func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.Attachment("attachment.txt", "attachment.txt")

	})
	e.GET("/index", func(c echo.Context) error {
		return c.File("./multiUpload.html")
	})
	e.POST("/upload", upload)
	e.POST("/multiUpload", multiUpload)
	e.Logger.Fatal(e.Start(":1335"))
}

Part 11 Websocket通信

go 复制代码
package main

import (
	"fmt"
	"github.com/gorilla/websocket"
	"github.com/labstack/echo"
	"github.com/labstack/echo/middleware"
)

var upgrader = websocket.Upgrader{}

func hello(c echo.Context) error {
	ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
	if err != nil {
		return err
	}
	defer ws.Close()
	for {
		err := ws.WriteMessage(websocket.TextMessage, []byte("hello world"))
		if err != nil {
			c.Logger().Error(err)
		}
		_, msg, err := ws.ReadMessage()
		if err != nil {
			c.Logger().Error(err)
		}
		fmt.Printf("%s\n", msg)
	}
}
func main() {
	e := echo.New()
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	e.Static("/", "./public")
	e.GET("/", func(c echo.Context) error {
		return c.File("./public/webtest.html")
	})
	e.GET("/ws", hello)
	e.Logger.Fatal(e.Start(":1330"))
}
相关推荐
什巳1 分钟前
JAVA练习278- 和为 K 的子数组
java·学习·算法·leetcode
碎光拾影35 分钟前
CPU与MCU核心区别揭秘
单片机·学习·51单片机
栈溢出了2 小时前
Redis 分片集群与哈希槽笔记
java·redis·笔记·spring
我命由我123452 小时前
复利极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
AOwhisky3 小时前
Python 学习笔记(第三期)——流程控制核心知识点自测与详解
开发语言·笔记·python·学习·云原生·运维开发·流程控制
tyqtyq223 小时前
药品说明书解读 —— AI 安全用药助手,鸿蒙原生应用深度解析
人工智能·学习·华为·生活·harmonyos
小心亦新4 小时前
STM32学习13 定时器1中断
stm32·嵌入式硬件·学习
我命由我123454 小时前
72 法则极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
qq_263_tohua5 小时前
第112期 CNN学习,不错的文章
学习
我想我不够好。5 小时前
满级的惩戒在范围
学习