protobuf

该博客介绍了如何在Gin Web框架中使用Protobuf进行数据序列化和反序列化。首先展示了如何将User结构体序列化为ProtoBuf格式并响应到HTTP请求中,然后详细讲解了客户端如何接收并反序列化这些数据,以恢复原始的User对象。此过程涉及Gin的Render接口和proto.Marshal方法的应用。
摘要由CSDN通过智能技术生成
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	a := []string{"1", "2", "3"}

	r.GET("/protobuf", func(c *gin.Context){
		data := &module.User{}
		c.ProtoBuf(200, data)
	})

	r.Run(":8080")
}

这是将信息,user进行序列化

// ProtoBuf serializes the given struct as ProtoBuf into the response body.
//二进制话,放入response体中
func (c *Context) ProtoBuf(code int, obj interface{}) {
	c.Render(code, render.ProtoBuf{Data: obj})
}

// ProtoBuf contains the given interface object.
type ProtoBuf struct {
	Data interface{}//data 对应任何类型
}

// Render writes the response headers and calls render.Render to render data.
func (c *Context) Render(code int, r render.Render) {
	c.Status(code)

	if !bodyAllowedForStatus(code) {
		r.WriteContentType(c.Writer)
		c.Writer.WriteHeaderNow()
		return
	}

	if err := r.Render(c.Writer); err != nil {
		panic(err)
	}
}

调用Render()函数,render.ProtoBuf{Data: obj}结构体为render.Render类型,原因在于它实现了Render的接口

// Render interface is to be implemented by JSON, XML, HTML, YAML and so on.
type Render interface {
	// Render writes data with custom ContentType.
	//这个通用的方法
	Render(http.ResponseWriter) error
	// WriteContentType writes custom ContentType.
	WriteContentType(w http.ResponseWriter)
}

JSON, XML, HTML, YAML都是通过实现其接口来实现的,看一下具体的实现方法

// Render (ProtoBuf) marshals the given interface object and writes data with custom ContentType.
func (r ProtoBuf) Render(w http.ResponseWriter) error {
	r.WriteContentType(w)
	//将data信息通过Marshal方法进行序列化
	bytes, err := proto.Marshal(r.Data.(proto.Message))
	if err != nil {
		return err
	}

	_, err = w.Write(bytes)
	return err
}

// WriteContentType (ProtoBuf) writes ProtoBuf ContentType.
func (r ProtoBuf) WriteContentType(w http.ResponseWriter) {
	writeContentType(w, protobufContentType)
}

protobuf定义十分简单,就只有一个Data字段,通过上述方法序列化到http.ResponseWriter

2.反序列化

package main

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"io/ioutil"
	"net/http"
)

func main() {
	//客户端发出请求,接收数据
	resp, err := http.Get("http://localhost:8080/protobuf")
	if err != nil {
		fmt.Println(err)
	}else {
		defer resp.Body.Close()
		//读出数据,返回为byte[]
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Println(err)
		}else {
			//对应protobuf形成的结构体
			user := &module.User{}
			//反序列化
			proto.UnmarshalMerge(body, user)
			fmt.Println(*user)
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值