go-echo学习笔记
go-echo学习笔记,包含了请求与响应,路由,参数解析,模版渲染,登录验证,日志,文件上传与下载,websocket通信。
文章目录
- Part1 Get与Post
- Part2 四种请求
- Part3 提取参数
- Part4 解析json与xml
- Part5 json传输
- Part6 模版渲染
- Part7 模版参数传递
- Part8 Cookie与Session
- Part9 JWT
- Part9 日志
- Part10 文件上传与下载
- Part 11 Websocket通信
Part1 Get与Post
主要内容包括登录网页,发送请求并进行处理
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,其中请求时,静态路由要大于参数路由大于匹配路由。
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请求,普通带问候的请求方式
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较为常用。
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传输
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 模版渲染
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 模版参数传递
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
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
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 日志
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 文件上传与下载
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通信
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"))
}