使用以下代码(摘自https://gist.github.com/miku/293f253b706c4de1b75c):
package main
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"log"
"net/http"
)
type Payload struct {
Name string
Location string
}
func 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 readFirst(w http.ResponseWriter, r *http.Request) {
log.Println("entering readFirst")
// 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(err)
}
// 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) {
readFirst(w, r)
readSecond(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))
}
关于go - 停止HTTP调用并使用一系列处理程序返回错误;可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62701908/