英文:
How to rewrite the response body and empty the original content in the middleware?
问题
希望输出替换数据
,但是尝试后输出的是原始数据
+替换数据
或者没有输出。
我想在中间件中重写响应体,只想输出替换数据
,参考如何在中间件中重写响应体?,我修改了我的代码如下:
请求被路由到:
ToolsGroup := Router.Group("")
ToolsGroup.Use(middleware.ToolsGroupPermission())
{
ToolsGroup.GET("/ptr", func(c *gin.Context) {
c.Data(http.StatusOK, "text/plain", []byte("原始数据"))
})
}
中间件是:
package middleware
import (
"bytes"
"github.com/gin-gonic/gin"
)
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
wb := &toolBodyWriter{
body: &bytes.Buffer{},
ResponseWriter: c.Writer,
}
c.Writer = wb
c.Next()
wb.body.Reset()
wb.Write([]byte("替换数据"))
//c.Data(http.StatusOK, "text/plain", []byte("替换数据"))
}
}
type toolBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (r toolBodyWriter) Write(b []byte) (int, error) {
return r.body.Write(b)
}
当上述代码被修改后,所有的[]bytes
都无法输出。
但是当注释掉以下部分时,参考被更改为如何在路由器中间件之后获取响应体?:
func (r toolBodyWriter) Write(b []byte) (int, error) {
r.body.Write(b)
return r.ResponseWriter.Write(b)
}
将同时输出原始数据
+替换数据
。但是要求只输出替换数据
。
英文:
Hope to output replace data
, but output origin data
+replace data
or no output after trying
I want to rewrite response body in middleware,Only want to output replace data
,Refer to How to rewrite response body in middleware?, modify my code as
Requests are routed to
ToolsGroup := Router.Group("")
ToolsGroup .Use(middleware.ToolsGroupPermission())
{
ToolsGroup .GET("/ptr", func(c *gin.Context) {
c.Data(http.StatusOK, "text/plain", []byte("orign data"))
})
}
Middleware is
package middleware
import (
"bytes"
"github.com/gin-gonic/gin"
)
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
wb := &toolBodyWriter{
body: &bytes.Buffer{},
ResponseWriter: c.Writer,
}
c.Writer = wb
c.Next()
wb.body.Reset()
wb.Write([]byte("replace data"))
//c.Data(http.StatusOK, "text/plain", []byte("replace data"))
}
}
type toolBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (r toolBodyWriter) Write(b []byte) (int, error) {
return r.body.Write(b)
}
When the above code is modified, all [] bytes
cannot be output.
But the reference is changed to how do i get response body in after router middleware?
when commenting:
func (r toolBodyWriter) Write(b []byte) (int, error) {
r.body.Write(b)
return r.ResponseWriter.Write(b)
}
Will output origin data
+replace data
at the same time. But the requirement is to output replace data
答案1
得分: 1
你不能撤销对r.ResponseWriter的写入。在确定要发送给客户端的内容之前,不要调用ResponseWriter.Write。
ToolsGroupPermission应该从缓冲区复制到c.Writer,或者调用c.Data。如果你计划替换响应,其他处理程序不应该访问原始的ResponseWriter:
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
buf := &bytes.Buffer{}
rw := c.Writer
c.Writer = buf
c.Next()
var replaceResponse bool
if replaceResponse {
c.Data(http.StatusOK, "text/plain", []byte("replace data"))
} else {
// TODO: Copy header and status code somehow. I'm not familiar enough with gin to know how to do that nicely.
io.Copy(rw, buf)
}
}
}
英文:
You cannot take back what you have written to r.ResponseWriter. Don't call ResponseWriter.Write before you know what you want to send to the client.
ToolsGroupPermission should either copy from the buffer to c.Writer, or call c.Data. There is no reason to even have the toolBodyWriter type; other handlers shouldn't have access to the original ResponseWriter if you plan to replace the response:
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
buf := &bytes.Buffer{}
rw := c.Writer
c.Writer = buf
c.Next()
var replaceResponse bool
if replaceResponse {
c.Data(http.StatusOK, "text/plain", []byte("replace data"))
} else {
// TODO: Copy header and status code somehow. I'm not familiar enough with gin to know how to do that nicely.
io.Copy(rw, buf)
}
}
}
答案2
得分: 0
package middleware
import (
"bytes"
"fmt"
"github.com/gin-gonic/gin"
)
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
wb := &toolBodyWriter{
body: &bytes.Buffer{},
ResponseWriter: c.Writer,
}
c.Writer = wb
c.Next()
originBytes := wb.body
fmt.Printf("%s", originBytes)
// clear Origin Buffer
wb.body = &bytes.Buffer{}
wb.Write([]byte("替换的数据"))
wb.ResponseWriter.Write(wb.body.Bytes())
//c.Data(http.StatusOK, "text/plain", []byte("替换的数据"))
}
}
type toolBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (r toolBodyWriter) Write(b []byte) (int, error) {
return r.body.Write(b)
}
或者
package middleware
import (
"bytes"
"fmt"
"github.com/gin-gonic/gin"
)
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
wb := &toolBodyWriter{
body: &bytes.Buffer{},
ResponseWriter: c.Writer,
status: Origin,
}
c.Writer = wb
c.Next()
wb.status = Replace
originBytes := wb.body
fmt.Printf("%s", originBytes)
// clear Origin Buffer
wb.body = &bytes.Buffer{}
wb.Write([]byte("替换的数据"))
//c.Data(http.StatusOK, "text/plain", []byte("替换的数据"))
}
}
type toolBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
status byte
}
const (
Origin byte = 0x0
Replace = 0x1
)
func (r toolBodyWriter) Write(b []byte) (int, error) {
if r.status == 0x1 {
r.body.Write(b)
return r.ResponseWriter.Write(b)
} else {
return r.body.Write(b) //r.ResponseWriter.Write(b)
}
}
英文:
package middleware
import (
"bytes"
"github.com/gin-gonic/gin"
)
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
wb := &toolBodyWriter{
body: &bytes.Buffer{},
ResponseWriter: c.Writer,
}
c.Writer = wb
c.Next()
originBytes := wb.body
fmt.Printf("%s", originBytes)
// clear Origin Buffer
wb.body = &bytes.Buffer{}
wb.Write([]byte("replace data"))
wb.ResponseWriter.Write(wb.body.Bytes())
//c.Data(http.StatusOK, "text/plain", []byte("replace data"))
}
}
type toolBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (r toolBodyWriter) Write(b []byte) (int, error) {
return r.body.Write(b)
}
Or
package middleware
import (
"bytes"
"github.com/gin-gonic/gin"
)
func ToolsGroupPermission() gin.HandlerFunc {
return func(c *gin.Context) {
wb := &toolBodyWriter{
body: &bytes.Buffer{},
ResponseWriter: c.Writer,
status: Origin,
}
c.Writer = wb
c.Next()
wb.status = Replace
originBytes := wb.body
fmt.Printf("%s", originBytes)
// clear Origin Buffer
wb.body = &bytes.Buffer{}
wb.Write([]byte("replace data"))
//c.Data(http.StatusOK, "text/plain", []byte("replace data"))
}
}
type toolBodyWriter struct {
gin.ResponseWriter
body *bytes.Buffer
status byte
}
const (
Origin byte = 0x0
Replace = 0x1
)
func (r toolBodyWriter) Write(b []byte) (int, error) {
if r.status == 0x1 {
r.body.Write(b)
return r.ResponseWriter.Write(b)
} else {
return r.body.Write(b) //r.ResponseWriter.Write(b)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论