上QQ阅读APP看书,第一时间看更新
How it works…
Once we run the program, the HTTP server will start locally listening on port 8080. Browsing http://localhost:8080 will show us an HTML form, as shown in the following screenshot:
Once we enter the username and password and click on the Login button, we will see Hello followed by the username as the response from the server, as shown in the following screenshot:
Let’s understand the changes we introduced as part of this recipe:
- Using import ( "fmt" "html/template" "log" "net/http" "github.com/gorilla/schema"), we imported two additional packages—fmt and github.com/gorilla/schema—which help to convert structs to and from Form values.
- Next, we defined the User struct type, which has Username and Password fields, as follows:
type User struct
{
Username string
Password string
}
- Then, we defined the readForm handler, which takes HTTP Request as an input parameter and returns User, as follows:
func readForm(r *http.Request) *User {
r.ParseForm()
user := new(User)
decoder := schema.NewDecoder()
decodeErr := decoder.Decode(user, r.PostForm)
if decodeErr != nil {
log.Printf("error mapping parsed form data to struct : ", decodeErr)
}
return user
}
Let's understand this Go function in detail:
- r.ParseForm(): Here we parse the request body as a form and put the results into both r.PostForm and r.Form.
- user := new(User): Here we create a new User struct type.
- decoder := schema.NewDecoder(): Here we are creating a decoder, which we will be using to fill a user struct with Form values.
- decodeErr := decoder.Decode(user, r.PostForm): Here we decode parsed form data from POST body parameters to a user struct.
r.PostForm is only available after ParseForm is called.
- if decodeErr != nil { log.Printf("error mapping parsed form data to struct : ", decodeErr) }: Here we check whether there is any problem with mapping form data to a struct. If there is, then log it.
Then, we defined a login handler, which checks if the HTTP request calling the handler is a GET request and then parses login-form.html from the templates directory and writes it to an HTTP response stream; otherwise, it calls the readForm handler, as follows:
func login(w http.ResponseWriter, r *http.Request)
{
if r.Method == "GET"
{
parsedTemplate, _ := template.ParseFiles("templates/
login-form.html")
parsedTemplate.Execute(w, nil)
}
else
{
user := readForm(r)
fmt.Fprintf(w, "Hello "+user.Username+"!")
}
}