Accéder à la réponse HTTP sous forme de chaîne dans Go

125

Je voudrais analyser la réponse d'une requête Web, mais j'ai du mal à y accéder sous forme de chaîne.

func main() {
    resp, err := http.Get("http://google.hu/")
    if err != nil {
        // handle error
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

    ioutil.WriteFile("dump", body, 0600)

    for i:= 0; i < len(body); i++ {
        fmt.Println( body[i] ) // This logs uint8 and prints numbers
    }

    fmt.Println( reflect.TypeOf(body) )
    fmt.Println("done")
}

Comment puis-je accéder à la réponse sous forme de chaîne? ioutil.WriteFileécrit correctement la réponse à un fichier.

J'ai déjà vérifié la référence du paquet mais ce n'est pas vraiment utile.

Tibor Szasz
la source

Réponses:

223

bs := string(body) devrait suffire à vous donner une chaîne.

À partir de là, vous pouvez l'utiliser comme une chaîne régulière.

Un peu comme dans ce fil :

var client http.Client
resp, err := client.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
    bodyBytes, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    bodyString := string(bodyBytes)
    log.Info(bodyString)
}

Voir également GoByExample .

Comme commenté ci-dessous (et dans la réponse de zzn ), il s'agit d'une conversion (voir les spécifications ). Voir " Combien coûte ? " (Problème inverse, mais la même conclusion s'applique) où zzzz a mentionné:
[]byte(string)

Certaines conversions sont identiques à une distribution, comme uint(myIntvar), qui réinterprète simplement les bits en place.

Sonia ajoute:

Faire une chaîne à partir d'une tranche d'octets, implique certainement l'allocation de la chaîne sur le tas. La propriété d'immuabilité le force.
Parfois, vous pouvez optimiser en faisant autant de travail que possible avec [] byte, puis en créant une chaîne à la fin. Le bytes.Buffertype est souvent utile.

VonC
la source
Merci. Avez-vous des suggestions sur la façon dont j'aurais pu le découvrir moi-même? Comment string () fait-il cela? Pourquoi ne puis-je pas le voir avec Reflect.TypeOf?
Tibor Szasz
1
@TiborSzasz C'est une simple conversion: voir blog.golang.org/slices#TOC_12 .
VonC
Une petite amélioration de votre code serait d'utiliser http.StatusOKau lieu de la 200valeur brute !
Shadoninja
J'ai fait cela et j'ai constaté que mes corps de requête ont toujours un caractère de nouvelle ligne à la fin. Est-ce normal pour un corps de requête ou est-ce que cela est justifié par ioutil.ReadAll()??
sixty4bit
30

La méthode que vous utilisez pour lire la réponse http body renvoie une tranche d'octets:

func ReadAll(r io.Reader) ([]byte, error)

documentation officielle

Vous pouvez convertir []byteen chaîne en utilisant

body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)
Tsabsch
la source
1

string (byteslice) convertira une tranche d'octet en chaîne, sachez simplement que ce n'est pas seulement une conversion de type, mais aussi une copie de mémoire.

zzn
la source