Acceder a la respuesta HTTP como cadena en Go

123

Me gustaría analizar la respuesta de una solicitud web, pero tengo problemas para acceder a ella como una cadena.

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")
}

¿Cómo puedo acceder a la respuesta como cadena? ioutil.WriteFileescribe correctamente la respuesta en un archivo.

Ya revisé la referencia del paquete, pero no es realmente útil.

Tibor Szasz
fuente

Respuestas:

221

bs := string(body) debería ser suficiente para darte una cuerda.

A partir de ahí, puede usarlo como una cadena normal.

Un poco como en este hilo :

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)
}

Consulte también GoByExample .

Como se comenta a continuación (y en la respuesta de zzn ), esta es una conversión (ver especificaciones ). Consulte " ¿Qué tan caro es ? " (Problema inverso, pero se aplica la misma conclusión) donde zzzz mencionó:
[]byte(string)

Algunas conversiones son iguales a un reparto, como uint(myIntvar), que simplemente reinterpreta los bits en su lugar.

Sonia agrega:

Hacer una cadena a partir de un segmento de bytes, definitivamente implica asignar la cadena en el montón. La propiedad de inmutabilidad fuerza esto.
A veces puede optimizar haciendo todo el trabajo posible con [] byte y luego creando una cadena al final. El bytes.Buffertipo suele ser útil.

VonC
fuente
Gracias. ¿Tiene alguna sugerencia de cómo podría haberlo descubierto por mi cuenta? ¿Cómo hace eso string ()? ¿Por qué no puedo verlo con reflect.TypeOf?
Tibor Szasz
1
@TiborSzasz Es una conversión simple: consulte blog.golang.org/slices#TOC_12 .
VonC
¡Una pequeña mejora en su código sería usar en http.StatusOKlugar del 200valor bruto !
Shadoninja
He estado haciendo esto y descubrí que mis cuerpos de solicitud siempre tienen un carácter de nueva línea al final. ¿Es esto normal para un organismo de solicitud o es causado por ioutil.ReadAll()?
sixty4bit
29

El método que está utilizando para leer la respuesta del cuerpo http devuelve un segmento de bytes:

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

documentación oficial

Puede convertir []bytea una cadena usando

body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)
tsabsch
fuente
1

string (byteslice) convertirá el segmento de bytes en una cadena, solo sepa que no es solo una conversión de tipo, sino también una copia de memoria.

zzn
fuente