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"`
       ...
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?