【问题标题】:Error when decoding JSON解码 JSON 时出错
【发布时间】:2016-03-31 13:26:42
【问题描述】:

在过去的几天里,我第一次尝试了 GO。

我有一个将其值传递给服务器的 HTML 表单。该服务器依次提取表单键/值并将它们放在 JSON 中。然后将此 JSON 发送到另一台服务器。

问题是:当第二台服务器尝试解码 JSON 时出现以下错误:

Error decoding JSON: json: cannot unmarshal string into Go value of type main.NewContainerJSON

1:原始 HTML 表单

<form method="post" action="http://127.0.0.1:8080/new-user" autocomplete ="on">
<table>
    <tr>
        <td colspan="2"><h1>Container Configuration</h1></td>
    </tr>
    <tr>
        <td><h2>Container Name</h2></td>
        <td><input type="text" name="containerName" placeholder = "My Container Name" required /></td>
    </tr>
    <tr>
        <td><h2>Base Server</h2></td>
        <td>
            <select name="BaseServer">
                <option value="Ubuntu 14.04">Ubuntu 14.04</option>
        </td>
    </tr>
    <tr>
        <td><h2>Content Management System</h2></td>
        <td>
            <select name="CMS">
                <option value="Wordpress">Wordpress</option>
        </td>
    </tr>
    <tr>
        <td><h2>Website Name</h2></td>
        <td><input type="text" name="websiteName" placeholder = "mysite.com" required /></td>
    </tr>
    <tr>
        <td><h2>New Root Database Password</h2> </td>
        <td><input type = "password" name = "dbRootPWD" placeholder = "password" required /></td>
    </tr>
    <tr>
        <td><h2>Database Admin Username</h2></td>
        <td><input type = "text" name = "dbAdminUname" placeholder = "Admin" required /></td>
    </tr>
    <tr>
        <td><h2>Database Admin Password</h2></td>
        <td><input type = "password" name = "dbAdminPwd" placeholder = "password" required /></td>
    </tr>
    <tr>
        <td></td>
        <td><input type = "submit" value = "submit"></td>
    </tr>
</table>    

2:第一个服务器代码

package main

import (
"fmt"
"encoding/json"
"net"
"net/http"
 )

type newContainerJSON struct {
    ContainerName string
    BaseServer string
    CMS string
    WebsiteName string
    DBrootPWD string
    DBadminUname string
    DBadminPWD string
}

func newUser(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()

    cName := r.FormValue("containerName")
    sName := r.FormValue("BaseServer")
    cmsName := r.FormValue("CMS")
    wsName := r.FormValue("websiteName")
    dbrootPwd := r.FormValue("dbRootPWD")
    dbadmName := r.FormValue("dbAdminUname")
    dbamdpwdName := r.FormValue("dbAdminPwd") 

    c := newContainerJSON {
        ContainerName: cName,
        BaseServer: sName,
        CMS: cmsName,
        WebsiteName: wsName,
        DBrootPWD: dbrootPwd,
        DBadminUname: dbadmName,
        DBadminPWD: dbamdpwdName,
    }

    d, _ := json.Marshal(c)
    s := string(d)
    fmt.Println(s)

    conn, err := net.Dial("tcp", "127.0.0.1:8081")
    checkError(err)

    encoder := json.NewEncoder(conn)

    encoder.Encode(d) 
}

func main() {
    http.HandleFunc("/new-user", newUser)
    err := http.ListenAndServe(":8080", nil) // setting listening port
    checkError(err)
}

func checkError(err error) {
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
     }
}

3:第二台服务器代码:

package main

import (
    "fmt"
    "net"
    "encoding/json"
)

type NewContainerJSON struct {
    ContainerName string    `json:",string"`
    BaseServer string       `json:",string"`
    CMS string              `json:",string"`
    WebsiteName string      `json:",string"`
    DBrootPWD string        `json:",string"`
    DBadminUname string     `json:",string"`
    DBadminPWD string       `json:",string"`
}

func main() {

    service := "127.0.0.1:8081"
    tcpAddr, err := net.ResolveTCPAddr("tcp", service)
    checkError(err)

    listener, err := net.ListenTCP("tcp", tcpAddr)
    checkError(err)

    conn, err := listener.Accept()
    checkError(err)

    decoder := json.NewDecoder(conn)

    var b NewContainerJSON
    err = decoder.Decode(&b)
    checkError(err)

    fmt.Println(b)

    conn.Close() // we're finished

}

func checkError(err error) {
    if err != nil {
        fmt.Println("An error occurred: ", err.Error())

    }
}

第二个服务器代码中的以下代码发生错误

var b NewContainerJSON
err = decoder.Decode(&b)
checkError(err)

fmt.Println(b)

我怀疑我没有正确解码 JSON,或者我遗漏了一些非常明显的东西。

【问题讨论】:

    标签: json go


    【解决方案1】:

    第一个服务器对值进行双重编码。结果是一个字符串。

    d, _ := json.Marshal(c) // d is []byte containing the JSON
    ...
    encoder.Encode(d)  // encoder writes base64 encoding of []byte as JSON string
    

    将代码改为:

    conn, err := net.Dial("tcp", "127.0.0.1:8081")
    if err != nil {
         // handle error
    }
    encoder := json.NewEncoder(conn)
    if err := encoder.Encode(c); err != nil {
       // handle error
    }
    

    【讨论】:

      【解决方案2】:

      当您执行encoder.Encode(d) 时,您正在对上一步的封送结果进行编码。所以当你把它解码回来时,你得到的不是 go 对象,而是一个字符串。

      相反,您可以这样做,encoder.Encode(c)。 (直接编码对象c)。

      这应该有助于你理解:http://play.golang.org/p/qNxqOJcj_a

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多