こんにちは。scarvizです。
先月にAndroidのアプリコンテストにエントリーしたのですが、その時に経路情報とかGCMとかを使う上で、JSONを触りました。
実は初めてちゃんとJSONに触れたんですね。
結構面白かったので、Go言語でもJSONやってみました。
基本的にここの内容の前半と同じです。
http://golang.org/doc/articles/json_and_go.html
■JSONの構造体
JSON用に構造体を用意します。
今回は以下を用意しました。
type Message struct {
Id int64
Data string
}
ここで気をつける点は、要素名の頭文字を大文字にしてエクスポートしておかないといけない点です。
うっかり小文字にしてて僕ははまってました・・・。
テストデータとしては以下を用意しました。
mes := Message{1, "JSONTest"}
■エンコーディング
エンコーディングはjson.Marshalを使用します。
引数はinterface型になっています。なので、構造体をそのまま渡します。
package main
import (
"encoding/json"
"fmt"
"os"
)
type Message struct {
Id int64
Data string
}
func main() {
mes := Message{1, "JSONTest"}
// JSONにエンコーディングする
bdata := EncodingJSON(mes)
// byteスライスを出力する
os.Stdout.Write(bdata)
}
/*
JSONにエンコーディングする
*/
func EncodingJSON(mes Message) []byte {
bdata, err := json.Marshal(mes)
if err != nil {
fmt.Println(err)
return nil
}
return bdata
}
結果:
{"Id":1,"Data":"JSONTest"}
■デコーディング
デコーディングはjson.Unmarshalを使用します。
第一引数にbyteスライス(JSON)を渡し、第二引数には構造体を参照渡しします。
package main
import (
"encoding/json"
"fmt"
)
type Message struct {
Id int64
Data string
}
func main() {
mes := Message{1, "JSONTest"}
// JSONにエンコーディングする
bdata, _ := json.Marshal(mes)
// JSONをデコーディングする
dmes := DecodingJSON(bdata)
// 構造体を出力する
fmt.Println(dmes)
}
/*
JSONにデコーディングする
*/
func DecodingJSON(bdata []byte) Message {
var mes Message
err := json.Unmarshal(bdata, &mes)
if err != nil {
fmt.Println(err)
return Message{-1, "err"}
}
return mes
}
結果:
{1 JSONTest}
デコーディング時にJSONのキーは大文字小文字を区別しないそうです。
DataでもDATAでもDaTaでもdaTaでも全部同じものとして扱います。
また、構造体に定義している要素がJSONのキーに無い場合は、ゼロ値が格納されます。
逆にJSONのキーにあって、構造体に定義していないものがある場合は、その値は無視されます。
package main
import (
"encoding/json"
"fmt"
"os"
)
type Message struct {
Id int64
Data string
}
func main() {
// JSONのキーが"DaTa"になってる場合
bdata1 := []byte(`{"Id":1,"DaTa":"JSONTest"}`)
os.Stdout.Write(bdata1)
fmt.Println("")
// JSONをデコーディングする
dmes1 := DecodingJSON(bdata1)
// 構造体を出力する
fmt.Println(dmes1)
fmt.Println("")
// JSONにIdがない場合
bdata2 := []byte(`{"DaTa":"JSONTest"}`)
os.Stdout.Write(bdata2)
fmt.Println("")
// JSONをデコーディングする
dmes2 := DecodingJSON(bdata2)
// 構造体を出力する
fmt.Println(dmes2)
fmt.Println("")
// JSONにTestという構造体で定義されていないキーが存在している場合
bdata3 := []byte(`{"Id":1,"DaTa":"JSONTest","Test":"Test"}`)
os.Stdout.Write(bdata3)
fmt.Println("")
// JSONをデコーディングする
dmes3 := DecodingJSON(bdata3)
// 構造体を出力する
fmt.Println(dmes3)
}
/*
JSONにデコーディングする
*/
func DecodingJSON(bdata []byte) Message {
var mes Message
err := json.Unmarshal(bdata, &mes)
if err != nil {
fmt.Println(err)
return Message{-1, "err"}
}
return mes
}
結果:
{"Id":1,"DaTa":"JSONTest"}
{1 JSONTest}
{"DaTa":"JSONTest"}
{0 JSONTest}
{"Id":1,"DaTa":"JSONTest","Test":"Test"}
{1 JSONTest}
■構造体の構造体
golang.orgのjson_and_goの後半には構造体の中に構造体を使用する方法もあったので紹介します。
構造体の中に構造体を使用する場合は次のように構造体のポインタ型で定義します。
package main
import (
"encoding/json"
"fmt"
"os"
)
type Message struct {
Id int64
Data *Datas
}
type Datas struct {
TestData1 string
TestData2 string
}
func main() {
mes := Message{1, &Datas{"JSONTest1","JSONTest2"}}
// JSONにエンコーディングする
bdata := EncodingJSON(mes)
// byteスライスを出力する
os.Stdout.Write(bdata)
fmt.Println("")
// JSONをデコーディングする
dmes := DecodingJSON(bdata)
// 構造体を出力する
fmt.Printf("Id:%d, [Data]TestData1:%s, TestData2:%s",
dmes.Id, dmes.Data.TestData1, dmes.Data.TestData2)
fmt.Println("")
}
/*
JSONにエンコーディングする
*/
func EncodingJSON(mes Message) []byte {
bdata, err := json.Marshal(mes)
if err != nil {
fmt.Println(err)
return nil
}
return bdata
}
/*
JSONにデコーディングする
*/
func DecodingJSON(bdata []byte) Message {
var mes Message
err := json.Unmarshal(bdata, &mes)
if err != nil {
fmt.Println(err)
return Message{-1, nil}
}
return mes
}
結果:
{"Id":1,"Data":{"TestData1":"JSONTest1","TestData2":"JSONTest2"}}
Id:1, [Data]TestData1:JSONTest1, TestData2:JSONTest2
golang.orgのjson_and_goの後半には他にも、JSONの構造が予め分かっていない場合とか、1行ずつ読み書きする方法とかも書いてますが、省略します。
今回最初に作成したエンコーディング・デコーディングのソースを以下に置いています。
http://goo.gl/sh7sO
0 件のコメント:
コメントを投稿