गो में पोस्ट अनुरोध में मैं JSON स्ट्रिंग कैसे भेजूं


244

मैंने Apiary के साथ काम करने की कोशिश की और JSON को नकली सर्वर भेजने के लिए एक सार्वभौमिक टेम्प्लेट बनाया और यह कोड है:

package main

import (
    "encoding/json"
    "fmt"
    "github.com/jmcvetta/napping"
    "log"
    "net/http"
)

func main() {
    url := "http://restapi3.apiary.io/notes"
    fmt.Println("URL:>", url)

    s := napping.Session{}
    h := &http.Header{}
    h.Set("X-Custom-Header", "myvalue")
    s.Header = h

    var jsonStr = []byte(`
{
    "title": "Buy cheese and bread for breakfast."
}`)

    var data map[string]json.RawMessage
    err := json.Unmarshal(jsonStr, &data)
    if err != nil {
        fmt.Println(err)
    }

    resp, err := s.Post(url, &data, nil, nil)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("response Status:", resp.Status())
    fmt.Println("response Headers:", resp.HttpResponse().Header)
    fmt.Println("response Body:", resp.RawText())

}

यह कोड JSON को ठीक से नहीं भेजता है, लेकिन मुझे नहीं पता कि क्यों। JSON स्ट्रिंग हर कॉल में अलग हो सकती है। मैं इसके Structलिए उपयोग नहीं कर सकता ।


मैं आपके द्वारा उपयोग किए जाने वाले कुछ पुस्तकालयों से परिचित नहीं हूं, लेकिन जैसा कि मैं इसे समझता हूं, आप Jsons का नक्शा भेजने की कोशिश कर रहे हैं। तुम सिर्फ कबाड़ के साथ स्ट्रिंग क्यों नहीं भेजते?
टोपो

1
यदि आप जौन को भेजना चाहते हैं तो आप जोंस को अनमर्ष क्यों कर रहे हैं?
जिमब

एक छोटी सी टिप, आप अपने संदेश को एक संरचना या मानचित्र [स्ट्रिंग] इंटरफ़ेस {} के रूप में बना सकते हैं जो आप चाहते हैं सभी मूल्यों को जोड़ने के लिए और फिर json.Marshall का उपयोग करके मानचित्र या संरचना को एक json में परिवर्तित करें।
टोपो

@topo, मैंने नैपिंग के सोर्स कोड में खोदा है, अगर पेलोड सेट किया गया है, तो वे json.Marshallउस पर कॉल करते हैं, मुझे यकीन नहीं है कि यह उसके लिए काम क्यों नहीं कर रहा था।
वनऑफने

जवाबों:


502

मैं नैपिंग से परिचित नहीं हूं, लेकिन गोलंग के net/httpपैकेज का उपयोग करना ठीक काम करता है ( खेल का मैदान ):

func main() {
    url := "http://restapi3.apiary.io/notes"
    fmt.Println("URL:>", url)

    var jsonStr = []byte(`{"title":"Buy cheese and bread for breakfast."}`)
    req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
    req.Header.Set("X-Custom-Header", "myvalue")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    fmt.Println("response Status:", resp.Status)
    fmt.Println("response Headers:", resp.Header)
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println("response Body:", string(body))
}

1
अब यह खेल के मैदान पर आतंक है। क्या आप कुछ ठीक कर सकते हैं या अपडेट कर सकते हैं?
16

9
@ यह खेल के मैदान पर काम नहीं कर सकता, मैंने इसे कोड पेस्ट करने के लिए इस्तेमाल किया था, आप इससे बाहरी कनेक्शन नहीं खोल सकते।
OneOfOne

8
ठोस बैंड नाम सुझाव के लिए @Altenrion +1।
चार्ली श्लिसेर

8
बस एक चेतावनी, भूल नहीं है कि डिफ़ॉल्ट रूप से golang http ग्राहक कभी नहीं का समय समाप्त, तो असली दुनिया के लिए, की तर्ज पर सेट कुछ करने के लिए सबसे अच्छाclient.Timeout = time.Second * 15
svarlamov

1
क्या यह सभी त्रुटियों को इकट्ठा / निरीक्षण करने के लिए अद्यतन किया जा सकता है? यह (मेरे लिए, कम से कम) गो में पोस्ट अनुरोध करने के लिए Google पर शीर्ष परिणाम है, और यह एक अच्छा जवाब है, लेकिन मुझे एक टन उदाहरण कोड दिखाई देता है जो सिर्फ त्रुटियों को नजरअंदाज करता है, और मुझे लगता है कि यह newbies में बुरे अभ्यास को प्रोत्साहित करता है। तो फिर, अगर कोई भी नियमित रूप से त्रुटियों को नजरअंदाज करता है, तो मुझे लगता है कि वे सीखेंगे कि आखिरकार क्यों नहीं, लेकिन शुरुआत के लिए अच्छे अभ्यास को प्रोत्साहित क्यों न करें?
। रोडा

103

आप बस postअपने json पोस्ट करने के लिए उपयोग कर सकते हैं ।

values := map[string]string{"username": username, "password": password}

jsonValue, _ := json.Marshal(values)

resp, err := http.Post(authAuthenticatorUrl, "application/json", bytes.NewBuffer(jsonValue))

3
मुझे यह त्रुटि मिलती है:cannot use jsonValue (type []byte) as type io.Reader in argument to http.Post: []byte does not implement io.Reader (missing Read method)
मंदार वेज ३०'१६

@MandarVaze मैं तुम्हें गलत हो सकता है लगता है io.Readerके लिए http.Post, और bytes.NewBuffer () मेरी कोड में अच्छी तरह से काम करता है
gaozhidf

1
मैं 1.7 पर हूं, अगर यह मायने रखता है। @OneOfOne द्वारा सूचीबद्ध कोड काम करता है (जो इसके बजाय इसका bytes.NewBuffer()उपयोग करता है लेकिन उपयोग करता http.NewRequestहै http.Post)
मंदार वज़े

2
Golang.org/pkg/net/http/#Post के अनुसार , " resp.Bodyइससे पढ़ने के दौरान कॉल करने वाले को बंद कर देना चाहिए । यदि प्रदान किया गया शरीर ए है , तो io.Closerयह अनुरोध के बाद बंद हो जाता है।" मैं कैसे बता सकता हूँ, एक गो नौसिखिया के रूप में, अगर शरीर एक है io.Closer, या दूसरे शब्दों में, अगर यह उदाहरण सुरक्षित है?
डेनिस

14

यदि आपके पास पहले से ही एक संरचना है।

type Student struct {
    Name    string `json:"name"`
    Address string `json:"address"`
}

// .....

body := &Student{
    Name:    "abc",
    Address: "xyz",
}

buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(body)
req, _ := http.NewRequest("POST", url, buf)

client := &http.Client{}
res, e := client.Do(req)
if e != nil {
    return e
}

defer res.Body.Close()

fmt.Println("response Status:", res.Status)
// Print the body to the stdout
io.Copy(os.Stdout, res.Body)

पूरा जिस्म


12

मानक नेट / http पैकेज के अलावा, आप मेरे GoRequest का उपयोग करने पर विचार कर सकते हैं जो नेट / http के चारों ओर लपेटता है और आपके जीवन को आसान बनाता है बिना json या संरचना के बारे में बहुत अधिक सोचने के बिना। लेकिन आप एक अनुरोध में दोनों को मिला सकते हैं और मेल कर सकते हैं! (आप इसके बारे में अधिक जानकारी गोरे गीथूब पेज में देख सकते हैं)

तो, अंत में आपका कोड निम्न प्रकार हो जाएगा:

func main() {
    url := "http://restapi3.apiary.io/notes"
    fmt.Println("URL:>", url)
    request := gorequest.New()
    titleList := []string{"title1", "title2", "title3"}
    for _, title := range titleList {
        resp, body, errs := request.Post(url).
            Set("X-Custom-Header", "myvalue").
            Send(`{"title":"` + title + `"}`).
            End()
        if errs != nil {
            fmt.Println(errs)
            os.Exit(1)
        }
        fmt.Println("response Status:", resp.Status)
        fmt.Println("response Headers:", resp.Header)
        fmt.Println("response Body:", body)
    }
}

यह इस बात पर निर्भर करता है कि आप कैसे हासिल करना चाहते हैं। मैंने इस लाइब्रेरी को इसलिए बनाया क्योंकि मुझे आपके साथ भी यही समस्या है और मुझे ऐसा कोड चाहिए जो छोटा हो, जोसन के साथ प्रयोग करने में आसान हो, और मेरे कोडबेस और प्रोडक्शन सिस्टम में अधिक टिकाऊ हो।


यदि GoRequest नेट / http को लपेटता है। क्या टीएलएस के लिए असुरक्षित प्रमाण पत्र को निष्क्रिय करने के लिए इसे जोड़ना संभव है? tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }
user1513388 17

46
@ user1513388 यह हमेशा एक भयानक विचार है कि किसी भी भाषा में किसी भी परिदृश्य में टीएलएस सत्यापन को छोड़ देने के कोड उदाहरणों का योगदान करने के लिए ... आप गलती से एक बहुत प्रतिलिपि / पेस्ट "वर्कअराउंड" को समाप्त कर सकते हैं जो कि नियोफाइट्स जो स्टैकऑवरफ्लो पर जाते हैं और फिक्सिंग की प्रकृति को नहीं समझते हैं। टीएलएस त्रुटियां महत्वपूर्ण हैं। या तो अपने प्रमाणपत्र आयात पथ को ठीक करें (यदि परीक्षण के लिए स्व-हस्ताक्षरित का उपयोग करें, उन्हें आयात करें) या अपनी मशीन की प्रमाण पत्र श्रृंखला को ठीक करें, या पता करें कि आपका सर्वर एक अवैध प्रमाणपत्र क्यों प्रस्तुत कर रहा है जिसे आपके ग्राहक द्वारा सत्यापित नहीं किया जा सकता है।
माइक एटलस

1
इस उत्तर के बारे में एक बात मुझे बिल्कुल पसंद नहीं है, यह जिस तरह से JSON ऑब्जेक्ट को बनाता है, जो इंजेक्शन के माध्यम से संभावित रूप से शोषक है। एक बेहतर तरीका यह होगा कि किसी वस्तु की रचना की जाए और फिर उसे JSON (उचित पलायन के साथ) में बदल दिया जाए।
जॉन व्हाइट

@ जॉनहाई मैं सहमत हूं, बहुत रूबी / जेएस /
पायथोनिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.