代码之家  ›  专栏  ›  技术社区  ›  antman1p

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

  •  -2
  • antman1p  · 技术社区  · 8 年前

    我正在尝试使用golang创建一个服务,该服务将在端口上侦听包含json的post请求,并希望解析出json的用户名和密码字段,并将其保存为变量,以便在函数外部用于验证Active Directory。 我正在使用HandleFunc()函数,但无法确定如何访问函数外部的变量。我试着创造一个回报,但没有成功。如何正确创建变量,然后在函数外部使用它们?

     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
    }
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   I159    8 年前

    您不能访问变量,不是因为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)
    

    更正确的方法是调用 ldapConn 在…内 http.HandleFunc 回调。

     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))
    
        2
  •  0
  •   Community CDub    8 年前

    如何使用HandleFunc()函数将json解析为变量 可在功能之外访问?

    从你的问题来看,我认为你不能在这里返回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 说。你打电话给你的 ldapConn 之后 ListenAndServe 这些行将永远不会执行,因为它已被阻塞。

    如果您想打印,您的应用程序已启动或失败。我认为该代码将帮助您:

        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())
        }