当前位置: 首页 > article >正文

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"))
}


http://www.kler.cn/a/505461.html

相关文章:

  • vue3+ts+element-plus 输入框el-input设置背景颜色
  • leetcode 面试经典 150 题:快乐数
  • Banana Pi BPI-RV2 RISC-V路由开发板采用矽昌通信SF2H8898芯片
  • C++实现设计模式---抽象工厂模式 (Abstract Factory)
  • 微信小程序获取openid
  • C语言:-三子棋游戏代码:分支-循环-数组-函数集合
  • 【Qt】01-了解QT
  • T-SQL编程
  • Python3 函数
  • 网安-HTML
  • 移动端H5缓存问题
  • 太速科技-402-基于TMS320C6678+XC7K325T的高性能计算核心板
  • 青少年编程与数学 02-006 前端开发框架VUE 27课题、TypeScript
  • 数字可调控开关电源设计(论文+源码)
  • C# 运算符和类型强制转换(对象的相等比较)
  • 深度学习|表示学习|作为损失函数的交叉熵|04
  • 单片机存储器和C程序编译过程
  • vue3封装el-tour漫游式引导
  • 09.VSCODE:安装 Git for Windows
  • .NetCore 使用 NPOI 读取带有图片的excel数据
  • 软件测试 —— Selenium(等待)
  • 物联网云平台:智能硬件芯片 esp32 的开放式管理设计
  • 【Elasticsearch复合查询】
  • 基于spingboot+html技术的博客网站
  • 1.1.1 C语言常用的一些函数(持续更新)
  • 最好用的图文识别OCR -- PaddleOCR(4) 模型微调