Go 停止HTTP调用并使用处理程序链返回错误;可能吗?
使用以下代码(取自):Go 停止HTTP调用并使用处理程序链返回错误;可能吗?,go,handler,middleware,Go,Handler,Middleware,使用以下代码(取自): 主程序包 进口( “字节” “编码/json” “io” “io/ioutil” “日志” “net/http” ) 类型有效负载结构{ 名称字符串 位置字符串 } func readSecond(w http.ResponseWriter,r*http.Request){ log.Println(“输入readSecond”) //r.Body是io.ReadCloser,这就是我们所知道的 b、 err:=ioutil.ReadAll(r.Body) 如果错误!=零{
主程序包
进口(
“字节”
“编码/json”
“io”
“io/ioutil”
“日志”
“net/http”
)
类型有效负载结构{
名称字符串
位置字符串
}
func readSecond(w http.ResponseWriter,r*http.Request){
log.Println(“输入readSecond”)
//r.Body是io.ReadCloser,这就是我们所知道的
b、 err:=ioutil.ReadAll(r.Body)
如果错误!=零{
log.Fatal(错误)
}
//关闭一个关闭器不会伤害任何人
延迟r.Body.Close()
Printf(“请求正文:%s”,字符串(b))
}
func readFirst(w http.ResponseWriter,r*http.Request){
log.Println(“输入readFirst”)
//临时缓冲区
b:=bytes.NewBuffer(make([]字节,0))
//TeeReader返回一个读卡器,该读卡器将从r.Body读取的内容写入b。
读卡器:=io.TEERADER(右主体,b)
//一些商业逻辑
var有效载荷
如果err:=json.NewDecoder(reader).Decode(&payload);err!=nil{
log.Fatal(错误)
}
//我们的身体完了
延迟r.Body.Close()
Printf(“来自正文的反序列化负载:%v”,负载)
//nocloser返回一个ReadCloser,其中包含一个no-op-Close方法,该方法包装提供的读取器r。
r、 Body=ioutil.nocloser(b)
}
func处理程序(w http.ResponseWriter,r*http.Request){
readFirst(w,r)
读秒(w,r)
}
func main(){
http.HandleFunc(“/”,handler)
log.Fatal(http.ListenAndServe(“:8080”,nil))
}
是否有方法阻止运行readSecond()
(第二个处理程序)
例如:
如果payload==”
我想退出HTTP调用并返回一个错误
有没有办法使用此代码执行此操作?
我知道我可以用嵌套中间件来实现。但是像这样的处理程序会怎么样呢?使用方法和接收器有助于更好地控制错误。 您不能在http的处理程序中定期返回错误
package main
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"log"
"net/http"
)
type Payload struct {
Name string
Location string
}
type Handle struct {
err error
}
func (h *Handle) readSecond(w http.ResponseWriter, r *http.Request) {
log.Println("entering readSecond")
// r.Body is a io.ReadCloser, that's all we know
b, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
// closing a NopCloser won't hurt anybody
defer r.Body.Close()
log.Printf("request body: %s", string(b))
}
func (h *Handle) readFirst(w http.ResponseWriter, r *http.Request) {
log.Println("entering readFirst")
h.err = nil
// temporary buffer
b := bytes.NewBuffer(make([]byte, 0))
// TeeReader returns a Reader that writes to b what it reads from r.Body.
reader := io.TeeReader(r.Body, b)
// some business logic
var payload Payload
if err := json.NewDecoder(reader).Decode(&payload); err != nil {
// log.Fatal("read first", err)
h.err = err
w.Write([]byte(err.Error()))
}
// we are done with body
defer r.Body.Close()
log.Printf("deserialized payload from body: %v", payload)
// NopCloser returns a ReadCloser with a no-op Close method wrapping the provided Reader r.
r.Body = ioutil.NopCloser(b)
}
func handler(w http.ResponseWriter, r *http.Request) {
var handle Handle
handle.readFirst(w, r)
if handle.err == nil {
handle.readSecond(w, r)
}
}
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
为了改变行为,必须进行一些更改,所以当你说“使用此代码”时,你试图避免什么样的更改?@Adrian尽可能少?有没有具体的原因说明你不能从
readFirst
返回错误?您的readX
函数都不需要满足HandlerFunc
类型。@kingkupps,您的意思是错误,这样我就可以在readFirst()
之后检查它了?是的!我在问为什么不先将签名func readFirst(w http.ResponseWriter,r*http.Request)设置为错误
,然后检查返回的错误或缺少错误。