在 GoLang 中,如何获取 HandleFunc() 函数以将 json 解析为函数外部可访问的变量

In GoLang How do I get the HandleFunc() function to parse a json into variables accesible outside of the function

我正在尝试使用 golang 创建一个服务,它将在端口上侦听包含 json 的 post 请求,并想解析 [=14] 的用户名和密码字段=] 并将它们保存为要在函数外部使用的变量,以向 Active Directory 进行身份验证。 我正在使用 HandleFunc() 函数,但无法确定如何访问函数外部的变量。我尝试创建一个 return,但它无法构建。如何正确创建变量然后在函数外使用它们?

 package main

 import (
         "gopkg.in/ldap.v2"
         "fmt"
         "net/http"
         "os"
         "encoding/json"
         "log"
         "crypto/tls"
         "html"

 )

 type Message struct {
     User string 
     Password string 
 }

 func main() {
     const SERVICE_PORT = "8080"


     var uname string
     var pwd string

     LDAP_SERVER_DOMAIN := os.Getenv("LDAP_DOM")
     if LDAP_SERVER_DOMAIN == "" {
        LDAP_SERVER_DOMAIN = "192.168.10.0" 
     }


     //Handle Http request and parse json
     http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
            var m Message

            if request.Body == nil {
            http.Error(w, "Please send a request body", 400)                
            return
            }

            err := json.NewDecoder(request.Body).Decode(&m)
            if err != nil {
                http.Error(w, err.Error(), 400)
                return
            }
            // Not sure what to do here
            uname = m.User
            pwd = m.Password
        })

     log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))

     connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)

     if connected == true {
        fmt.Println("Connected is", connected)
     }


 }


// Connects to the ldap server and returns true if successful
 func ldapConn(dom, user, pass string) bool {
    // For testing go insecure
    tlsConfig := &tls.Config{InsecureSkipVerify: true}

    conn, err := ldap.DialTLS("tcp", dom, tlsConfig)
    if err != nil {
        // error in connection
        log.Println("ldap.DialTLS ERROR:", err)

        //debug
        fmt.Println("Error", err)

        return false
    }
    defer conn.Close()
    err = conn.Bind(user, pass)
    if err != nil {
        // error in ldap bind
        log.Println(err)

        //debug
        log.Println("conn.Bind ERROR:", err)

        return false
    }
    return true
}

How do I get the HandleFunc() function to parse a json into variables accesible outside of the function?

根据你的问题,我认为你不能在此处 return json 值。相反,您可以将结构传递给函数并在其中调用它们。 例如:

//Handle Http request and parse json
     http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
            var m Message

            if request.Body == nil {
            http.Error(w, "Please send a request body", 400)                
            return
            }

            err := json.NewDecoder(request.Body).Decode(&m)
            if err != nil {
                http.Error(w, err.Error(), 400)
                return
            }
            // Not sure what to do here
            // pass the variable to your function
            uname = m.User
            pwd = m.Password

            // passed your struct to a function here and do your logic there.
            yourFunction(m)
        })

并且您可以在另一个包或与您定义处理程序的包相同的包中编写yourFunction(m Message)。例如写 yourFunction() 将是:

func yourFunction(m Message){
   // do your logic here
}

如果函数在另一个包中

//call your package where your struct is defined.
func yourFunction(m main.Message){
   // do your logic here
}

正如JimB所说。你在 ListenAndServe 之后调用你的 ldapConn 这些行将永远不会被执行,因为它被阻止了。

如果您想打印您的应用程序已启动或失败。我认为这段代码会对您有所帮助:

    log.Println("App started on port = ", port)
    err := http.ListenAndServe(":"+port, nil)
    if err != nil {
        log.Panic("App Failed to start on = ", port, " Error : ", err.Error())
    }

您不能访问变量,不是因为 Go 名称空间不允许,而是因为 ListenAndServe 正在阻塞并且 ldapConn 只有在服务器停止时才能调用。

 log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))
 // Blocked until the server is listening and serving.

 connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)

更正确的方法是在 http.HandleFunc 回调中调用 ldapConn

 http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
        var m Message

        if request.Body == nil {
            http.Error(w, "Please send a request body", 400)                
            return
        }

        err := json.NewDecoder(request.Body).Decode(&m)
        if err != nil {
            http.Error(w, err.Error(), 400)
            return
        }

        connected := ldapConn(LDAP_SERVER_DOMAIN, m.User, m.Password)
        if connected == true {
            fmt.Println("Connected is", connected)
        }
 })

 log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))