##### 有如下需求:
##### 1) 给应用系统分类,确定组成部份,并构建一个关系树(左树)
##### 如 一个应用系统 按功能来划分成 web,api,db,cache,mq等等组成, 应用系统作为一级根,web,api这些作为二级根,服务名称,主机名,cpu,mem,disk作为三级展示. 有些应用并非使用到 如 mq, 所以二极根是动态变化的.
#####如下代码有些问题,求指导: 怎样获取整个json数据
```
package main
import (
"encoding/json"
"fmt"
)
type Systree struct {
Sysname []Sys `"json:sysname"`
}
type Sys struct {
Web []Detail1 `"json:web"`
App []Detail1 `"json:app"`
DB []Detail1 `"json:db"`
}
type Detail1 struct {
Name string `"json:name"`
Ip string `"json:ip"`
Cpu string `"json:cpu"`
Mem string `"json:mem"`
Disk string `json:disk`
}
func main() {
body := `
{
"sys1": {
"web": [
{
"name": "web-01-www-01",
"ip": "10.1.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
},
{
"name": "web-01-www-02",
"ip": "10.1.69.102",
"cpu": "2",
"mem": "4",
"disk": "40"
}
],
"app": {
"name": "app-01-www-01",
"ip": "10.2.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
},
"db": {
"name": "db-01-www-01",
"ip": "10.2.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
}
},
"sys2": {
"web": {
"name": "web-02-www-01",
"ip": "10.3.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
}
}
}
`
var r Systree
err := json.Unmarshal([]byte(body), &r)
if err != nil {
fmt.Printf("err was %v", err)
}
fmt.Println(r)
fmt.Println(len(r.Sysname))
fmt.Println(r.Sysname[0].Web[0].Name)
}
```
更多评论
```go
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type Systree map[string]*Sys
type Sys struct {
WebArr []Detail1 `json:"web"`
AppArr []Detail1 `json:"app"`
DBArr []Detail1 `json:"db"`
}
func (self *Sys) UnmarshalJSON(b []byte) error {
fmt.Println("Sys Unmarshal")
m := map[string]interface{}{}
if err := json.Unmarshal(b, &m); err != nil {
//fmt.Println("1 err:", err)
return err
}
t := reflect.TypeOf(*self)
val := reflect.ValueOf(self)
val = reflect.Indirect(val)
n := t.NumField()
for i := 0; i < n; i++ {
sf := t.Field(i)
tag := sf.Tag.Get("json")
name := sf.Name
v := m[tag]
if _v, ok := v.(map[string]interface{}); ok {
v = []interface{}{_v}
}
//fmt.Printf("tag: %v, v:%#v\n", sf.Tag, v)
fv := val.FieldByName(name)
//fmt.Printf("fv:%v, name:%v\n", fv, name)
fb, err := json.Marshal(v)
if err != nil {
//fmt.Println("2 err:", err)
return err
}
err = json.Unmarshal(fb, fv.Addr().Interface())
if err != nil {
//fmt.Println("3 err:", err)
return err
}
//fmt.Printf("fb: %v\n", string(fb))
//fmt.Printf("fv:%v, name:%v\n", fv, name)
}
return nil
}
type Detail1 struct {
Name string `json:"name"`
Ip string `json:"ip"`
Cpu string `json:"cpu"`
Mem string `json:"mem"`
Disk string `json:"disk"`
}
func main() {
body := `
{
"sys1": {
"web": [
{
"name": "web-01-www-01",
"ip": "10.1.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
},
{
"name": "web-01-www-02",
"ip": "10.1.69.102",
"cpu": "2",
"mem": "4",
"disk": "40"
}
],
"app": {
"name": "app-01-www-01",
"ip": "10.2.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
},
"db": {
"name": "db-01-www-01",
"ip": "10.2.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
}
},
"sys2": {
"web": {
"name": "web-02-www-01",
"ip": "10.3.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
}
}
}
`
r := make(Systree)
err := json.Unmarshal([]byte(body), &r)
if err != nil {
fmt.Printf("err: %v\n", err)
}
for k, v := range r {
fmt.Printf("k: %#v\n", k)
fmt.Printf("v: %#v\n", v)
}
fmt.Println(len(r))
}
```
#1
package main
import (
"encoding/json"
"fmt"
"reflect"
)
type Systree map[string]*Sys
type Sys struct {
WebArr []Detail1 `json:"web"`
AppArr []Detail1 `json:"app"`
DBArr []Detail1 `json:"db"`
}
func (self *Sys) UnmarshalJSON(b []byte) error {
fmt.Println("Sys Unmarshal")
m := map[string]interface{}{}
if err := json.Unmarshal(b, &m); err != nil {
//fmt.Println("1 err:", err)
return err
}
t := reflect.TypeOf(*self)
val := reflect.ValueOf(self)
val = reflect.Indirect(val)
n := t.NumField()
for i := 0; i < n; i++ {
sf := t.Field(i)
tag := sf.Tag.Get("json")
name := sf.Name
v := m[tag]
if _v, ok := v.(map[string]interface{}); ok {
v = []interface{}{_v}
}
//fmt.Printf("tag: %v, v:%#v\n", sf.Tag, v)
fv := val.FieldByName(name)
//fmt.Printf("fv:%v, name:%v\n", fv, name)
fb, err := json.Marshal(v)
if err != nil {
//fmt.Println("2 err:", err)
return err
}
err = json.Unmarshal(fb, fv.Addr().Interface())
if err != nil {
//fmt.Println("3 err:", err)
return err
}
//fmt.Printf("fb: %v\n", string(fb))
//fmt.Printf("fv:%v, name:%v\n", fv, name)
}
return nil
}
type Detail1 struct {
Name string `json:"name"`
Ip string `json:"ip"`
Cpu string `json:"cpu"`
Mem string `json:"mem"`
Disk string `json:"disk"`
}
func main() {
body := `
{
"sys1": {
"web": [
{
"name": "web-01-www-01",
"ip": "10.1.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
},
{
"name": "web-01-www-02",
"ip": "10.1.69.102",
"cpu": "2",
"mem": "4",
"disk": "40"
}
],
"app": {
"name": "app-01-www-01",
"ip": "10.2.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
},
"db": {
"name": "db-01-www-01",
"ip": "10.2.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
}
},
"sys2": {
"web": {
"name": "web-02-www-01",
"ip": "10.3.69.101",
"cpu": "2",
"mem": "4",
"disk": "40"
}
}
}
`
r := make(Systree)
err := json.Unmarshal([]byte(body), &r)
if err != nil {
fmt.Printf("err: %v\n", err)
}
for k, v := range r {
fmt.Printf("k: %#v\n", k)
fmt.Printf("v: %#v\n", v)
}
fmt.Println(len(r))
}
#2