英文:
Error when decoding JSON
问题
我最近第一次尝试使用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>
</form>
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,或者我遗漏了一些非常明显的东西。
英文:
I have been experimenting with GO for the first time, over the last few days.
I have a HTML form that passes it's values to a server. This server in turn extracts the form keys/ values and places them inside a JSON. This JSON is then sent to another server.
The issue is: I get the following error when the second server attempts to decode the JSON:
Error decoding JSON: json: cannot unmarshal string into Go value of type main.NewContainerJSON
1: The original HTML form
<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>
</form>
2: The first servers code
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: The second servers code:
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())
}
}
The error occurs with following code in the second servers code
var b NewContainerJSON
err = decoder.Decode(&b)
checkError(err)
fmt.Println(b)
I suspect I am not decoding the JSON properly or I am missing something very obvious.
答案1
得分: 3
第一个服务器对值进行了双重编码。结果是一个字符串。
d, _ := json.Marshal(c) // d 是包含 JSON 的 []byte
...
encoder.Encode(d) // encoder 将 []byte 的 base64 编码作为 JSON 字符串写入
将代码更改为:
conn, err := net.Dial("tcp", "127.0.0.1:8081")
if err != nil {
// 处理错误
}
encoder := json.NewEncoder(conn)
if err := encoder.Encode(c); err != nil {
// 处理错误
}
英文:
The first server is double encoding the value. The result is a string.
d, _ := json.Marshal(c) // d is []byte containing the JSON
...
encoder.Encode(d) // encoder writes base64 encoding of []byte as JSON string
Change the code to:
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
得分: 1
当你执行encoder.Encode(d)
时,你正在对前一步骤的编组结果进行编码。因此,当你解码它时,你得到的不是Go对象,而是一个字符串。
相反,你可以执行encoder.Encode(c)
(直接对对象c
进行编码)。
这应该能帮助你理解:http://play.golang.org/p/qNxqOJcj_a
英文:
When you do encoder.Encode(d)
, you are encoding the marshaled result from previous step. So when you decode it back you don't get the go object, but a string.
Instead you can do, encoder.Encode(c)
. (Directly encode the object c
).
This should help you understand: http://play.golang.org/p/qNxqOJcj_a
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论