당신은 JSON Unmarshal에 오류를 무시하고는 :
func Unmarshal(data []byte, v interface{}) error
가 오류를 반환 참조하십시오. 그 안에 추가,
err = json.Unmarshal(body, &record)
perror(err)
그것은 유니 코드 오류입니다 - 당신은 decode the UTF-16 data해야합니다.
어떻게해야합니까? this answer을보십시오. 기본적으로 body, err := ioutil.ReadAll(res.Body)
과 같이 본문을 읽으면 UTF-16 바이트를 문자열로 디코드하려고합니다. 거기에 많은 일이 있지만, 우리는 몇 가지 자유를 취할 수 있습니다 : 예를 들어, 크롬에서 URL을 당겨, 브라우저는 그것이 UTF - 16 르임을 알려줍니다. ByteOrder 탐지를 건너 뛸 수 있습니다. 그래서 여기에 핵심이 기능입니다 :
func UTF16BytesToString(b []byte, o binary.ByteOrder) string {
utf := make([]uint16, (len(b)+(2-1))/2)
for i := 0; i+(2-1) < len(b); i += 2 {
utf[i/2] = o.Uint16(b[i:])
}
if len(b)/2 < len(utf) {
utf[len(utf)-1] = utf8.RuneError
}
return string(utf16.Decode(utf))
}
우리의 바이트 순서를 알고 그것을 전달은,이 UTF-16 문자열로 순진한 바이트 배열을 변환합니다. 사용자 OneOfOne의 comment 덕분에 BOM을 쉽게 감지 할 수 있습니다.
결과 :
package main
import (
"encoding/binary"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"unicode/utf16"
"unicode/utf8"
)
const alertsUrl = "http://www.oref.org.il/WarningMessages/alerts.json"
type Record struct {
Id string `json:id`
Title string `json:title`
Data []string `json:data`
}
// LazyUTF16BytesToString converts UTF-16 encoded bytes, in big or little endian byte order,
// to a UTF-8 encoded string.
func LazyUTF16BytesToString(b []byte) string {
if len(b)%2 != 0 {
panic("len(b) % 2 != 0")
}
var codec binary.ByteOrder = binary.LittleEndian
if b[0] == 0xFE && b[1] == 0xFF { //check and strip the BOM
b = b[2:]
codec = binary.BigEndian
} else if b[0] == 0xFF && b[1] == 0xFE {
b = b[2:]
}
utf := make([]uint16, (len(b)+(2-1))/2)
for i := 0; i+(2-1) < len(b); i += 2 {
utf[i/2] = codec.Uint16(b[i:])
}
if len(b)/2 < len(utf) {
utf[len(utf)-1] = utf8.RuneError
}
return string(utf16.Decode(utf))
}
func main() {
client := &http.Client{}
req, err := http.NewRequest("GET", alertsUrl, nil)
perror(err)
req.Header.Add("Content-Type", "application/json; charset=utf-8")
res, err := client.Do(req)
perror(err)
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
perror(err)
bodyString := LazyUTF16BytesToString(body)
var record Record
err = json.Unmarshal([]byte(bodyString), &record)
perror(err)
fmt.Println(record)
}
func perror(err error) {
if err != nil {
panic(err)
}
}
** 오류를 무시 ** 중지 지금 여기에 질문을하기 전에 모든 오류를 확인하십시오. – Wessie
@Wessie 무시한 오류를 알려주시겠습니까? –
아 ... 글쎄, 나는 잘 모르겠다. 다시 확인하면 Unmarshal 메서드의 서명에 오류가 반환 된 것을 볼 수 있습니다. 나는이 길을 걸을거야. –