Frage: Derzeit drucke ich meine Antwort func Index
wie fmt.Fprintf(w, string(response))
folgt aus. Wie kann ich JSON in der Anforderung ordnungsgemäß senden, damit es möglicherweise von einer Ansicht verwendet wird?
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"net/http"
"log"
"encoding/json"
)
type Payload struct {
Stuff Data
}
type Data struct {
Fruit Fruits
Veggies Vegetables
}
type Fruits map[string]int
type Vegetables map[string]int
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
response, err := getJsonResponse();
if err != nil {
panic(err)
}
fmt.Fprintf(w, string(response))
}
func main() {
router := httprouter.New()
router.GET("/", Index)
log.Fatal(http.ListenAndServe(":8080", router))
}
func getJsonResponse()([]byte, error) {
fruits := make(map[string]int)
fruits["Apples"] = 25
fruits["Oranges"] = 10
vegetables := make(map[string]int)
vegetables["Carrats"] = 10
vegetables["Beets"] = 0
d := Data{fruits, vegetables}
p := Payload{d}
return json.MarshalIndent(p, "", " ")
}
Antworten:
Sie können Ihren Inhaltstyp-Header so festlegen, dass Clients wissen, dass sie json erwarten
Eine andere Möglichkeit, eine Struktur für json zu marshallen, besteht darin, einen Encoder mit dem zu erstellen
http.ResponseWriter
quelle
w.Header().Set("Content-Type", "application/json")
das Einstellen des Inhaltstyps korrekt ist, wird bei Verwendungjson.NewEncoder
stattdessen kein txt / plain-Ergebnis angezeigt. Bekommt sonst noch jemand das? Die Antwort von @poorva funktionierte wie erwartetw.WriteHeader(http.StatusOk)
bekomme ich das obige Ergebnis.w.WriteHeader(http.StatusOk)
bekomme ichtext/plain; charset=utf-8
, wenn ich den Status-Code nicht explizit setze, bekomme ichapplicaton/json
und die Antwort hat immer noch einen Status-Code 200.Changing the header map after a call to WriteHeader (or Write) has no effect unless the modified headers are trailers.
w.Header().Set("Content-Type", "application/json")
obigenjson.NewEncoder(w).Encode(p)
Arbeit für michAndere Benutzer kommentieren , dass das
Content-Type
ist ,plain/text
wenn codiert. Sie müssenContent-Type
zuerstw.Header().Set
den HTTP-Antwortcode und dann den HTTP-Antwortcode festlegenw.WriteHeader
.Wenn Sie
w.WriteHeader
zuerst anrufen, rufenw.Header().Set
Sie an, nachdem Sie erhalten habenplain/text
.Ein Beispielhandler könnte so aussehen.
quelle
Sie können so etwas in Ihrer
getJsonResponse
Funktion tun -quelle
jData
möglicherweise unnötig ein Byte-Slice verwendet wird.Data
kann abhängig von den gemarshallten Daten eine beliebige Größe haben, so dass dies eine nicht triviale Speicherverschwendung sein kann. Nach dem Marshalling kopieren wir aus dem Speicher in denResponseWriter
Stream. Die Antwort, die json.NewEncoder () usw. verwendet, würde den gemarshallten JSON direkt in denResponseWriter
(in seinen Stream ..)Encoder.Encode()
Funktion hinzuIm gobuffalo.io Framework habe ich es so gemacht:
und wenn ich dann eine JSON-Antwort für diese Ressource erhalten möchte, muss ich "Content-type" auf "application / json" setzen und es funktioniert.
Ich denke, Rails hat eine bequemere Möglichkeit, mit mehreren Antworttypen umzugehen. Bisher habe ich bei Gobuffalo nicht dasselbe gesehen.
quelle
Sie können diesen Paket-Renderer verwenden . Ich habe geschrieben, um diese Art von Problem zu lösen. Es ist ein Wrapper für JSON, JSONP, XML, HTML usw.
quelle