Je veux créer une fonction pour traiter n'importe quel type de formulaire. Je veux qu'elle soit capable de traiter tous les types de données. J'essaie d'utiliser une interface pour réaliser cette tâche.
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
Je veux obtenir, avec l'interface, le même résultat que celui que j'obtiens avec le type de données "Personne".
// 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
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Mise à jour
Je veux essayer de mieux expliquer mon problème. Peut-être que cette mise à jour sera plus claire.
// 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>
-
J'ai essayé toutes ces différentes variations. Une seule fonctionne, je vous explique plus bas.
-
Cela fonctionne parfaitement si j'utilise "var form Login" au lieu de "var from interface{}". Mais j'ai besoin qu'il puisse fonctionner avec n'importe quel type de données, donc j'ai besoin qu'il fonctionne avec interface{}.
-
J'ai eu une sortie "réussie", juste avec un des essais de l'interface{} :
$ curl -X POST http://localhost:8080/loginForm -H 'content-type : application/json' -d '{ "user" : "manu", "password" : "123" }''
output:"html"{"password":"123","user":"manu"}
- Mais lorsque je l'utilise dans un formulaire HTML, sur un navigateur, avec le modèle que j'ai posté, j'obtiens ce qui suit :
sortie : "html "null
- Je ne suis pas sûr que ce que j'obtiens (point 3) soit vraiment une sortie réussie. Quand j'utilise la var Login, ça marche bien, avec curl et brower, la sortie est inversée :
$ curl -X POST http://localhost:8080/loginForm -H 'content-type : application/json' -d '{ "user" : "manu", "password" : "123" }''
ouput:"html"{"user":"manu","password":"123"}
C'est la seule information que j'ai pu obtenir jusqu'à présent.