go ioutil.NopCloser 的使用

原理

NopCloser 的原理很简单,就是将一个不带 CloseReader 封装成 ReadCloser。以下是源码:

// NopCloser returns a ReadCloser with a no-op Close method wrapping
// the provided Reader r.
func NopCloser(r Reader) ReadCloser {
	return nopCloser{r}
}

type nopCloser struct {
	Reader
}

func (nopCloser) Close() error { return nil }

使用场景

我有一个服务 A 和服务 B,主要负责数据存储,用户请求会发送给服务 A ,此时服务 A 会去检查用户发送的数据内容,若是有重要的信息,则会将该用户发送的数据转发给服务 B。此时为服务 A 添加一个中间件拦截请求,在此判断是否要将数据发送给服务 B

示意图:
使用场景示意

示意代码:
这里只给服务 A 的相关代码。由于已经读取过 RequestBody 数据了,后续再读会读不到,所以这里需要自己重新再构建一个 ReadCloser 赋值给原先的 Body,用 NopCloser 简单的包装一下。

package main

import (
	"bytes"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"net/http"
)

func main() {
	engineA := gin.Default()
	engineA.Use(hasXiaohong)
	engineA.Run(":12345")
}

func hasXiaohong(c *gin.Context) {
	data, err := ioutil.ReadAll(c.Request.Body)
	if err != nil {
		c.String(http.StatusBadRequest, err.Error())
		c.Abort()
		return
	}
	defer c.Request.Body.Close()

	if bytes.Contains(data, []byte("小红")) {
		// 发送给服务 B
		// 数据封装
		http.Post("服务 B 的地址", "contentType", bytes.NewBuffer(data))
	}

	// 注意这时 c.Request.Body 已经读完了,需要重新将读出来的值给放回去,之后的处理就依然可以使用 c.Request.Body 了。
	bufReader := bytes.NewBuffer(data) // 这只是一个 Reader
	c.Request.Body = ioutil.NopCloser(bufReader) // 这边通过 NopCloser 包装成 ReadCloser
}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值