Я хочу создать функцию для обработки любых форм.
Я хочу, чтобы он мог обрабатывать любые типы данных.
Я пытаюсь использовать интерфейс для выполнения этой задачи.
type Person struct {
name string
lastName string
}
func HTMLForm(c *gin.Context) {
var f Person
c.ShouldBind(&f)
c.JSON(http.StatusOK, f)
}
// with this function i get the correct info
// output: {"name":"john","lastName":"snow"}
func HTMLForm(c *gin.Context) {
var f interface{}
c.ShouldBind(&f)
c.JSON(http.StatusOK, f)
}
// when i use the interface to make it usefull for any type of that
// i get null
// output: null
func HTMLForm(c *gin.Context) {
var f interface{}
ShouldBindJSON(f)
c.JSON(http.StatusOK, f)
}
// output: null
Я хочу получить с интерфейсом тот же вывод, что и с типом данных "Person".
// Another example of how i am using f
type Login struct {
User string
Password string
}
func main() {
router := gin.Default()
router.POST("/loginForm", func(c *gin.Context) {
var f interface{}
if err := c.ShouldBind(&f); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, f)
})
// Listen and serve on 0.0.0.0:8080
router.Run(":8080")
}
// output: null
/////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////
Обновление
Я хочу попытаться объяснить мою проблему лучше.
Может быть, это обновление более понятно.
// Golang code
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
// Binding from JSON
type Login struct {
User string `form:"user" json:"user" xml:"user" binding:"required"`
Password string `form:"password" json:"password" xml:"password" binding:"required"`
}
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*")
router.GET("/login", GetLogin)
router.POST("/loginJSON", PostJSONForm)
router.POST("/loginXML", PostXMLForm)
router.POST("/loginForm", PostHTMLForm)
/*
sudo lsof -n -i :8080
kill -9 <PID>
*/
router.Run(":8080")
}
func GetLogin(c *gin.Context) {
c.HTML(http.StatusOK, "login.tmpl", nil)
}
// Example for binding JSON ({"user": "manu", "password": "123"})
// curl -v -X POST http://localhost:8080/loginJSON -H 'content-type: application/json' '{ "user": "manu", "password"="123" }'
func PostJSONForm(c *gin.Context) {
//var json Login
var json interface{}
//var form map[string]interface{}
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
/*
if json.User != "manu" || json.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
*/
c.JSON(http.StatusOK, "json")
c.JSON(http.StatusOK, json)
}
// Example for binding XML (
// <?xml version="1.0" encoding="UTF-8"?>
// <root>
// <user>user</user>
// <password>123</password>
// </root>)
// curl -v -X POST http://localhost:8080/loginXML -H 'content-type: application/json' -d '{ "user": "manu", "password"="123" }'
func PostXMLForm(c *gin.Context) {
//var xml Login
var xml interface{}
//var form map[string]interface{}
if err := c.ShouldBindXML(&xml); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
/*
if xml.User != "manu" || xml.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
*/
c.JSON(http.StatusOK, "xml")
c.JSON(http.StatusOK, xml)
}
// Example for binding a HTML form (user=manu&password=123)
// curl -v -X POST http://localhost:8080/loginForm -H 'content-type: application/json' -d '{ "user": "manu", "password":"123" }'
func PostHTMLForm(c *gin.Context) {
//var form Login
var form interface{}
//var form map[string]interface{}
// This will infer what binder to use depending on the content-type header.
if err := c.ShouldBind(&form); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
/*
if form.User != "manu" || form.Password != "123" {
c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
return
}
c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
*/
c.JSON(http.StatusOK, "html")
c.JSON(http.StatusOK, form)
}
//Template
<h1>Login</h1>
<form action="/loginForm" method="POST">
<label>user:</label><br>
<input type="text" name="user"><br>
<label>password:</label><br>
<input type="text" name="password"><br>
<input type="submit">
</form>
Я пробовал все это разные варианты. Работает только одна, я объясню подробнее ниже.
Это прекрасно работает, если я использую «var form Login» вместо «var from interface {}». Но мне нужно, чтобы он мог работать с любым типом данных, поэтому мне нужно, чтобы он работал с интерфейсом {}.
У меня был "успешный" вывод, только с одним из интерфейсов {} попытки:
$ curl -X POST http://localhost:8080/loginForm -H 'content-type: application / json' -d '{"user": "manu", "password": "123"}'
выход: "HTML" { "пароль": "123", "пользователь": "Мана"}
- Но когда я использую его в форме HTML, в браузере, с тем шаблоном, который я разместил, я получаю:
вывод: "html" null
- Я не уверен, что то, что я получаю (пункт 3), действительно успешный вывод Когда я использую переменную Login, она работает нормально, с curl и brower, вывод ее инвертируется:
$ curl -X POST http://localhost:8080/loginForm -H 'content-type: application / json' -d '{"user": "manu", "password": "123"}'
Ouput: "HTML" { "пользователь": "Мана", "пароль": "123"}
Это вся информация, которую я мог получить до сих пор.