Uzyskaj dostęp do odpowiedzi HTTP jako ciąg w Go


123

Chciałbym przeanalizować odpowiedź żądania internetowego, ale mam problem z dostępem do niej jako ciągu.

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

Jak mogę uzyskać dostęp do odpowiedzi w postaci ciągu? ioutil.WriteFilezapisuje poprawnie odpowiedź do pliku.

Sprawdziłem już numer referencyjny pakietu, ale nie jest to zbyt pomocne.

Odpowiedzi:


221

bs := string(body) powinno wystarczyć, aby dać ci ciąg.

Stamtąd możesz użyć go jako zwykłego ciągu.

Trochę jak w tym wątku :

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

Zobacz także GoByExample .

Dalej należy zauważyć, poniżej (oraz w ZZN „s odpowiedź ), to konwersja (patrz specyfikacja ).
Zobacz „ Ile to kosztuje []byte(string)? ” (Odwrotny problem, ale obowiązuje ten sam wniosek), gdzie zzzz wspomniał:

Niektóre konwersje są takie same jak rzutowanie, na przykład uint(myIntvar), które po prostu reinterpretuje bity w miejscu.

Sonia dodaje:

Tworzenie łańcucha z kawałka bajtu zdecydowanie obejmuje przydzielenie ciągu na stercie. Wymusza to własność niezmienności.
Czasami możesz zoptymalizować, wykonując jak najwięcej pracy z bajtem [], a następnie tworząc na końcu łańcuch. bytes.BufferTyp jest często użyteczne.


Dzięki. Czy masz jakieś sugestie, jak mogłem sam to rozgryźć? Jak to robi string ()? Dlaczego nie mogę tego zobaczyć z Reflect.TypeOf?
Tibor Szasz

1
@TiborSzasz To prosta konwersja: patrz blog.golang.org/slices#TOC_12 .
VonC

Niewielkim ulepszeniem twojego kodu byłoby użycie http.StatusOKzamiast surowej 200wartości!
Shadoninja

Robiłem to i stwierdziłem, że moje ciała żądań zawsze mają na końcu znak nowej linii. Czy jest to normalne w przypadku treści żądania, czy jest to spowodowane ioutil.ReadAll()??
sixty4bit

29

Metoda, której używasz do odczytywania odpowiedzi treści http, zwraca fragment bajtu:

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

oficjalna dokumentacja

Możesz przekonwertować []bytena ciąg przy użyciu

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

1

string (byteslice) przekonwertuje kawałek bajtu na łańcuch, po prostu wiedz, że jest to nie tylko zwykła konwersja typów, ale także kopiowanie pamięci.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.