golang struct只是从json部分解组

时间:2017-10-22 15:25:09

标签: json go struct unmarshalling

我正在尝试将json转换为golang嵌套结构。它只是部分工作。大多数字段都没有正确解析,尽管有些字段可以解析。为什么来自json的所有数据都不会转换为golang结构?我的猜测是我的json格式和golang结构之间有一些错误,但我没有看到它。发布以解决问题。

当我运行程序时,机器的IP地址是未编组的,但测试运行ID不是。这是我的主要方法的输出:

test run id:
machine ip:172.25.148.39

这是我的golang代码:

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
}

这是json被转换:

{
  "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 个答案:

答案 0 :(得分:2)

在你的JSON中,你有一个拼写错误(一个额外的冒号)。您拨打有问题的字段"Id:"而不是"Id"。删除:,代码应该有效!

请注意,您的NodeId字段也可能无法填充,因为在JSON中,您将其称为"NodeId (cluster)"而不是"NodeId"。字段名称必须与JSON和Go完全匹配。如果要在JSON中使用与Go中不同的字段名称,请使用JSON名称注释结构:

type Example struct {
   Name string   `json:"firstName"`
   ...
}