http에서 JSON 응답을 얻는 방법.얻다
웹에서 JSON 데이터를 읽으려고 하는데 빈 결과가 반환됩니다.내가 여기서 뭘 잘못하고 있는지 모르겠어.
package main
import "os"
import "fmt"
import "net/http"
import "io/ioutil"
import "encoding/json"
type Tracks struct {
Toptracks []Toptracks_info
}
type Toptracks_info struct {
Track []Track_info
Attr []Attr_info
}
type Track_info struct {
Name string
Duration string
Listeners string
Mbid string
Url string
Streamable []Streamable_info
Artist []Artist_info
Attr []Track_attr_info
}
type Attr_info struct {
Country string
Page string
PerPage string
TotalPages string
Total string
}
type Streamable_info struct {
Text string
Fulltrack string
}
type Artist_info struct {
Name string
Mbid string
Url string
}
type Track_attr_info struct {
Rank string
}
func get_content() {
// json data
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"
res, err := http.Get(url)
if err != nil {
panic(err.Error())
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
var data Tracks
json.Unmarshal(body, &data)
fmt.Printf("Results: %v\n", data)
os.Exit(0)
}
func main() {
get_content()
}
가장 이상적인 방법은 이 기능을 사용하지 않는 것입니다.ioutil.ReadAll
디코더를 리더로 직접 사용합니다.여기 URL을 가져와 응답을 디코딩하는 좋은 함수가 있습니다.target
구조.
var myClient = &http.Client{Timeout: 10 * time.Second}
func getJson(url string, target interface{}) error {
r, err := myClient.Get(url)
if err != nil {
return err
}
defer r.Body.Close()
return json.NewDecoder(r.Body).Decode(target)
}
사용 예:
type Foo struct {
Bar string
}
func main() {
foo1 := new(Foo) // or &Foo{}
getJson("http://example.com", foo1)
println(foo1.Bar)
// alternately:
foo2 := Foo{}
getJson("http://example.com", &foo2)
println(foo2.Bar)
}
기본값을 사용하지 마십시오.*http.Client
이 답변이 원래 설명한 대로 생산 구조! (그것이 바로http.Get
/etc 콜처)를 참조해 주세요.그 이유는 디폴트클라이언트에는 타임아웃이 설정되어 있지 않기 때문입니다.리모트 서버가 응답하지 않으면, 일진이 나빠집니다.
문제는 데이터의 슬라이스 선언입니다.structs
(단,Track
, 슬라이스하면 안 됩니다.이것은 가져온 json 파일의 다소 우스꽝스러운 필드 이름에 의해 복합되어 구조 태그를 통해 수정할 수 있습니다(godoc 참조).
다음 코드는 json을 성공적으로 구문 분석했습니다.더 궁금하신 점이 있으시면 말씀해주세요.
package main
import "fmt"
import "net/http"
import "io/ioutil"
import "encoding/json"
type Tracks struct {
Toptracks Toptracks_info
}
type Toptracks_info struct {
Track []Track_info
Attr Attr_info `json: "@attr"`
}
type Track_info struct {
Name string
Duration string
Listeners string
Mbid string
Url string
Streamable Streamable_info
Artist Artist_info
Attr Track_attr_info `json: "@attr"`
}
type Attr_info struct {
Country string
Page string
PerPage string
TotalPages string
Total string
}
type Streamable_info struct {
Text string `json: "#text"`
Fulltrack string
}
type Artist_info struct {
Name string
Mbid string
Url string
}
type Track_attr_info struct {
Rank string
}
func perror(err error) {
if err != nil {
panic(err)
}
}
func get_content() {
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"
res, err := http.Get(url)
perror(err)
defer res.Body.Close()
decoder := json.NewDecoder(res.Body)
var data Tracks
err = decoder.Decode(&data)
if err != nil {
fmt.Printf("%T\n%s\n%#v\n",err, err, err)
switch v := err.(type){
case *json.SyntaxError:
fmt.Println(string(body[v.Offset-40:v.Offset]))
}
}
for i, track := range data.Toptracks.Track{
fmt.Printf("%d: %s %s\n", i, track.Artist.Name, track.Name)
}
}
func main() {
get_content()
}
json 패키지에서 사용하려면 구조물에 대문자 속성 이름이 필요합니다.
대문자 속성 이름은 다음과 같습니다.exported properties
. 소문자 속성 이름은 내보내지 않습니다.
또한 참조로 데이터 개체를 전달해야 합니다( ).&data
).
package main
import "os"
import "fmt"
import "net/http"
import "io/ioutil"
import "encoding/json"
type tracks struct {
Toptracks []toptracks_info
}
type toptracks_info struct {
Track []track_info
Attr []attr_info
}
type track_info struct {
Name string
Duration string
Listeners string
Mbid string
Url string
Streamable []streamable_info
Artist []artist_info
Attr []track_attr_info
}
type attr_info struct {
Country string
Page string
PerPage string
TotalPages string
Total string
}
type streamable_info struct {
Text string
Fulltrack string
}
type artist_info struct {
Name string
Mbid string
Url string
}
type track_attr_info struct {
Rank string
}
func get_content() {
// json data
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"
res, err := http.Get(url)
if err != nil {
panic(err.Error())
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
var data tracks
json.Unmarshal(body, &data)
fmt.Printf("Results: %v\n", data)
os.Exit(0)
}
func main() {
get_content()
}
결과json.Unmarshal
(에)var data interface{}
)는 바둑 유형과 변수 선언과 직접 일치하지 않습니다.예를들면,
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
)
type Tracks struct {
Toptracks []Toptracks_info
}
type Toptracks_info struct {
Track []Track_info
Attr []Attr_info
}
type Track_info struct {
Name string
Duration string
Listeners string
Mbid string
Url string
Streamable []Streamable_info
Artist []Artist_info
Attr []Track_attr_info
}
type Attr_info struct {
Country string
Page string
PerPage string
TotalPages string
Total string
}
type Streamable_info struct {
Text string
Fulltrack string
}
type Artist_info struct {
Name string
Mbid string
Url string
}
type Track_attr_info struct {
Rank string
}
func get_content() {
// json data
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=c1572082105bd40d247836b5c1819623&format=json&country=Netherlands"
url += "&limit=1" // limit data for testing
res, err := http.Get(url)
if err != nil {
panic(err.Error())
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err.Error())
}
var data interface{} // TopTracks
err = json.Unmarshal(body, &data)
if err != nil {
panic(err.Error())
}
fmt.Printf("Results: %v\n", data)
os.Exit(0)
}
func main() {
get_content()
}
출력:
Results: map[toptracks:map[track:map[name:Get Lucky (feat. Pharrell Williams) listeners:1863 url:http://www.last.fm/music/Daft+Punk/_/Get+Lucky+(feat.+Pharrell+Williams) artist:map[name:Daft Punk mbid:056e4f3e-d505-4dad-8ec1-d04f521cbb56 url:http://www.last.fm/music/Daft+Punk] image:[map[#text:http://userserve-ak.last.fm/serve/34s/88137413.png size:small] map[#text:http://userserve-ak.last.fm/serve/64s/88137413.png size:medium] map[#text:http://userserve-ak.last.fm/serve/126/88137413.png size:large] map[#text:http://userserve-ak.last.fm/serve/300x300/88137413.png size:extralarge]] @attr:map[rank:1] duration:369 mbid: streamable:map[#text:1 fulltrack:0]] @attr:map[country:Netherlands page:1 perPage:1 totalPages:500 total:500]]]
좋아, 얘들아, 난 이 일에 시간을 허비했어. 왜냐하면 위의 해결책들 중 어느 것도 나에게 효과가 없었기 때문이야.
- 그래서 저는 위의 첫 번째 구조체의 "탑트랙" 예시와 같이 첫 번째 계층에 맞게 이름을 "트랙"으로 변경했습니다.
- 다른 문제는 속성 "Attr"을 가진 구조 "Toptracks_info"에서 발생하였습니다.문제는 응답에 "@attr"이 표시되며 속성 이름 지정에 유효하지 않은 문자이기 때문에 @를 입력할 수 없다는 것입니다.
json:"@attr"
(이미지 배열의 "#text"에도 동일하게 적용됩니다.예를 들어 다음과 같습니다.
그리고 메인은
type Tracks struct {
Tracks Toptracks_info
}
type Toptracks_info struct {
Track []Track_info
Attr Attr_info `json:"@attr"`
}
type Track_info struct {
Name string
Duration string
Listeners string
Mbid string
Url string
Streamable Streamable_info
Artist Artist_info
Image []Image
Attr Track_attr_info
}
type Image struct {
Text string `json:"#text"`
Size string
}
type Attr_info struct {
Country string
Page string
PerPage string
TotalPages string
Total string
}
type Streamable_info struct {
Text string
Fulltrack string
}
type Artist_info struct {
Name string
Mbid string
Url string
}
type Track_attr_info struct {
Rank string
}
url := "http://ws.audioscrobbler.com/2.0/?method=geo.gettoptracks&api_key=xxxxxxxx&format=json&country=Netherlands"
res, err := http.Get(url)
body, err := ioutil.ReadAll(res.Body)
var data Tracks
json.Unmarshal(body, &data)
if err != nil {
panic(err.Error())
}
바둑은 처음이라 좀 미치겠어요.
언급URL : https://stackoverflow.com/questions/17156371/how-to-get-json-response-from-http-get
'programing' 카테고리의 다른 글
PostgreSQL 반환 결과를 JSON 어레이로 설정하시겠습니까? (0) | 2023.03.13 |
---|---|
부분 뷰를 바인딩하기 위해 ko.applyBindings를 호출할 수 있습니까? (0) | 2023.03.13 |
SQL에서 JSON으로 - SQL 2016에서 객체 배열에서 값 배열로 (0) | 2023.03.13 |
JSON 구문은 오브젝트에 중복된 키를 허용합니까? (0) | 2023.03.13 |
서비스 데이터 변경 시 범위 값 업데이트 (0) | 2023.03.13 |