doushenyu2537 2017-10-22 15:25
浏览 31
已采纳

golang结构仅部分从json解组

I am trying to convert json into a golang nested struct. It is only partially working. Most fields do not parse correctly, although some do. Why doesn't all the data from json get converted into a golang struct? My guess is that I have some mistake between my json format and the golang struct, but I don't see it. Posting to get some other eyes on the problem.

When I run the program, the machine ip address is unmarshalled, but the test run id is not. Here is the output from my main method:

test run id:
machine ip:172.25.148.39

Here is my golang code:

package main

import (
    "encoding/json"
    "bytes"
    "io/ioutil"
    "runtime"
    "log"
)

func main() {
    var testRunConfig TestRunConfig
    testRunConfigJson := ReadFile("testrun-config.json")
    err := json.Unmarshal([]byte(testRunConfigJson), &testRunConfig)
    if err != nil {
        HandleError(err)
    }

    println("test run id:" + testRunConfig.Id)
    println("machine ip:" + testRunConfig.Machines[0].IP)
}

//Logs the error, the function and the line number where it was generated
func HandleError(err error) (bool) {
    b := false

    if err != nil {
        // notice that we're using 1, so it will actually log the where
        // the error happened, 0 = this function, we don't want that.
        pc, fn, line, _ := runtime.Caller(1)

        log.Printf("[error] in %s[%s:%d] %v", runtime.FuncForPC(pc).Name(), fn, line, err)
        b = true
        panic(err)
    }

    return b
}


func ReadFile(fileName string) string {
    dat, err := ioutil.ReadFile(fileName)
    HandleError(err)
    return string(dat)
}

//http://json2struct.mervine.net/
type Machine struct {
    IP         string
    Interfaces []Interface
    Containers []Container
    CmdBuffer  bytes.Buffer
}

type InetAddress struct {
    Addr string
    DelayMS  int
}

type Interface struct {
    Name          string
    InetAddresses []InetAddress
}

type Volume struct {
    Localhost string
    Volume    string
}

type NetworkTopology struct {
    Host string
    Port string
}

type Container struct {
    Image           string
    Mem             string
    Cpu             float64
    Disk            string
    Volume          Volume
    NodeId          int
    ServiceType     string
    InstanceId      string
    Port            string
    NetworkTopology []NetworkTopology
    Args            map[string]string

    //"machine" element being a member of a Container is helpful for code flow/logic,
    //but is not required as part of the data model (it's duplicate data).
    //This is why it's private (not capitalized).  Think of it as a "transient" in java.
    machine         Machine
}

type TestRunConfig struct {
    Id       string
    Machines []Machine
}

And here is the json being converted:

{
  "Id:": "testRunId",
  "Machines": [
    {
      "Ip": "172.25.148.39",
      "Interfaces": [
        {
          "Name": "ems3f0",
          "InetAddresses": [
            {
              "Addr": "10.0.0.x/16",
              "DelayMS": 0
            }
          ]
        },
        {
          "Name": "ems3f1",
          "InetAddresses": [
            {
              "Addr": "10.5.0.x/16",
              "DelayMS": 5
            },
            {
              "Addr": "10.15.0.x/16",
              "DelayMS": 15
            },
            {
              "Addr": "10.25.0.x/16",
              "DelayMS": 25
            }
          ]
        }
      ],
      "Containers": [
        {
          "Image": "docker-core:1",
          "Mem": "20GB",
          "Cpu": 1.0,
          "Disk": "20GB",
          "Volume": {
            "Localhost": "/mnt/md0/${containerId}",
            "Volume": "/root/.btcd${containerId}"
          },
          "NodeId": 0,
          "ServiceType": "core",
          "InstanceId": "core1",
          "Port": "f(nodeid, serviceid, instanceId -> port #)",
          "NetworkTopology": [
            {
              "Host": "ip.address",
              "Port": "some.port"
            }
          ],
          "Args": {
            "database": "${volume}/init-data.csv.tgz",
            "listenPort": "1234",
            "sendPort": "1234"
          }
        },
        {
          "Image": "docker-wallet:1",
          "Mem": "20GB",
          "Cpu": 1.0,
          "Disk": "20GB",
          "Volume": {
            "Localhost": "/mnt/md0/${containerId}",
            "Volume": "/root/.btcd${containerId}"
          },
          "NodeId (cluster)": 0,
          "ServiceType": "wallet",
          "InstanceId": "1...100",
          "Port": "portNum",
          "Args": {
            "Database": "${volume}/init-data.csv.tgz",
            "ListenPort": "1234",
            "SendPort": "1234"
          }
        }
      ]
    }
  ]
}
  • 写回答

1条回答 默认 最新

  • dongweicha6077 2017-10-22 15:46
    关注

    In your JSON, you have a typo (an extra colon). You call the field in question "Id:" instead of "Id". Remove the : and the code should work!

    Note that your NodeId field will also likely not populate, because in the JSON, you call it "NodeId (cluster)" instead of "NodeId". The field names must match exactly in JSON and Go. If you want to use different field names in JSON than in Go, annotate your struct with the JSON names:

    type Example struct {
       Name string   `json:"firstName"`
       ...
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装