英文:
In GoLang How do I get the HandleFunc() function to parse a json into variables accesible outside of the function
问题
我正在尝试使用Go语言创建一个服务,该服务将在一个端口上监听POST请求,该请求包含JSON数据,并且我想解析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
}
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
}
以上是你提供的代码的翻译。
英文:
I am trying to create a service using golang that will listen on a port for a post request containing json and would like to parse out the username and password fields of the json and save those as variables to be used outside of the function to authenticate to Active Directory.
I am using the HandleFunc() fucntion, but cannot ficure out how to access the variables outside of the function. I tried creating a return, but it wouldn't build. How do I properly create the variables and then use them outside of the function?
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
}
答案1
得分: 1
你无法访问变量的原因不是因为Go的命名空间不允许,而是因为ListenAndServe
是阻塞的,只有在服务器停止时才能调用ldapConn
。
更正确的方法是在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))
英文:
You can't access the variables not because Go namespaces not allow it but because ListenAndServe
is blocking and ldapConn
could be called only if the server is stopped.
log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))
// Blocked until the server is listening and serving.
connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)
A more correct approach is to call ldapConn
inside http.HandleFunc
callback.
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
如何使HandleFunc()函数解析JSON并将其转换为函数外部可访问的变量?
根据你的问题,我认为你不能在这里返回JSON值。相反,你可以将结构体传递给一个函数,并在函数内部调用它们。
例如:
// 处理HTTP请求并解析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
}
// 不确定在这里该怎么做
// 将变量传递给你的函数
uname := m.User
pwd := m.Password
// 在这里将你的结构体传递给一个函数,并在那里进行逻辑处理。
yourFunction(m)
})
你可以在另一个包或与定义处理程序相同的包中编写yourFunction(m Message)
。例如,编写yourFunction()
的代码如下:
func yourFunction(m Message) {
// 在这里进行逻辑处理
}
如果函数在另一个包中:
// 调用定义了你的结构体的包。
func yourFunction(m main.Message) {
// 在这里进行逻辑处理
}
正如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())
}
英文:
> How do I get the HandleFunc() function to parse a json into variables
> accesible outside of the function?
from your question I don't think you can return the json value here. Instead you could pass the struct to a function and call them inside it.
for example :
//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)
})
and you can write yourFunction(m Message)
in another package or the same package as you define your handler. for example writing yourFunction()
would be :
func yourFunction(m Message){
// do your logic here
}
if function is in another package
//call your package where your struct is defined.
func yourFunction(m main.Message){
// do your logic here
}
as JimB said. You're calling your ldapConn
after ListenAndServe
those lines would never be executed since it is blocked.
and if you like to print your app is started or failed. I think this code will help you :
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())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论