我目前正在Golang编写代码来处理POST请求并将数据存储到MySQL数据库中。
这是我到目前为止所写的内容。
package main
import (
"fmt"
"os"
"log"
"net/http"
"database/sql"
"golang.org/x/crypto/bcrypt"
_ "github.com/go-sql-driver/mysql"
)
var myLogger *log.Logger
var db *sql.DB
var err error
type UserRegistrationData struct {
email string
password string
}
func handler(w http.ResponseWriter, r *http.Request) {
myLogger = log.New(os.Stdout, "INFO: ", log.LstdFlags)
var email string = r.PostFormValue("email")
var password string = r.PostFormValue("password")
data := UserRegistrationData{email, password}
jsonEncoded, _ := json.Marshal(data)
myLogger.Println("Success")
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
_, err = db.Exec("INSERT INTO users (email, password) VALUES (?, ?)", email, hashedPassword)
}
func initialiseDB() {
db, err := sql.Open("mysql", "root:@/authenticationgolang")
if err != nil {
panic(err.Error())
}
defer db.Close()
}
func main() {
initialiseDB()
http.HandleFunc("/call", handler)
http.ListenAndServe(":8080", nil)
}
当我运行代码并尝试保存数据时,我不断收到以下消息。
unexpected end of stream on Connection{10.10.10.153:8080, proxy=DIRECT@hostAddress=/10.10.10.153:8080 cipherSuite=none protocol=http/1.1}
日志似乎指出这行存在问题,我想请某人解决这个问题。
_, err = db.Exec("INSERT INTO users (email, password) VALUES (?, ?)", email, hashedPassword)
已添加以下是我在控制台上收到的日志消息。
2017/05/18 14:47:52 http: panic serving 10.10.10.58:41668: runtime error: invalid memory address or nil pointer dereference
goroutine 20 [running]:
net/http.(*conn).serve.func1(0xc4201360a0)
/usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:1721 +0xd0
panic(0x1288b60, 0x1424e70)
/usr/local/Cellar/go/1.8.1/libexec/src/runtime/panic.go:489 +0x2cf
database/sql.(*DB).conn(0x0, 0x14027c0, 0xc420010450, 0xc420034801, 0x10000000142ec80, 0x1600960, 0x2)
/usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:896 +0x3a
database/sql.(*DB).exec(0x0, 0x14027c0, 0xc420010450, 0x12e699d, 0x31, 0xc420045c58, 0x2, 0x2, 0x1, 0x0, ...)
/usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:1183 +0xb9
database/sql.(*DB).ExecContext(0x0, 0x14027c0, 0xc420010450, 0x12e699d, 0x31, 0xc420045c58, 0x2, 0x2, 0x126ed20, 0xc42013c440, ...)
/usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:1165 +0xbc
database/sql.(*DB).Exec(0x0, 0x12e699d, 0x31, 0xc420034c58, 0x2, 0x2, 0x3c, 0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.8.1/libexec/src/database/sql/sql.go:1179 +0x85
main.handler(0x14022c0, 0xc42014a0e0, 0xc420144100)
/Users/marshall/documents/projects/authenticationgolang/helloworld.go:40 +0x530
net/http.HandlerFunc.ServeHTTP(0x12ea668, 0x14022c0, 0xc42014a0e0, 0xc420144100)
/usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:1942 +0x44
net/http.(*ServeMux).ServeHTTP(0x142e060, 0x14022c0, 0xc42014a0e0, 0xc420144100)
/usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:2238 +0x130
net/http.serverHandler.ServeHTTP(0xc42009a2c0, 0x14022c0, 0xc42014a0e0, 0xc420144100)
/usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:2568 +0x92
net/http.(*conn).serve(0xc4201360a0, 0x1402780, 0xc42011e580)
/usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:1825 +0x612
created by net/http.(*Server).Serve
/usr/local/Cellar/go/1.8.1/libexec/src/net/http/server.go:2668 +0x2ce
答案 0 :(得分:2)
从您收到的错误消息:
运行时错误:无效的内存地址或无指针取消引用 goroutine 20 [正在运行]:
db
中的hanlder()
变量是零,这是原因的根源。
要解决此问题,您可以删除:
中的initialiseDB()
。因为在这里你被分配给函数中的新变量local而不是你的全局变量。像这样:
func initialiseDB() {
var err error
db, err = sql.Open("mysql", "root:@/authenticationgolang")
if err != nil {
panic(err.Error())
}
}
<强> 建议 强>
然后在您的代码上,请检查函数返回的错误值,如:
data := UserRegistrationData{email, password}
jsonEncoded, err := json.Marshal(data)
if err !=nil {
myLogger.Fatal(err)
}
myLogger.Println("Success")
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
myLogger.Fatal(err)
}
_, err = db.Exec("INSERT INTO users (email, password) VALUES (?, ?)", email, hashedPassword)
if err != nil {
myLogger.Fatal(err)
}
或者您可以使用Println()
,以防您不想停止您的应用程序运行:
if err != nil {
myLogger.Println(err)
return
}
返回将停止执行代码。使用这种方法,您会注意到服务器端是否发生了某些错误,并且您知道错误发生在哪一行。
如果请求成功,请不要忘记发送您的回复:
resp := struct {
Message string
}{
Message : "your message",
}
// Write the response
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(resp)
希望它有所帮助。