go 语言的http 包可以很方便的构建一个简单的http server
下面我们通过代码来熟悉go 的http 包
package growth
import (
"net/http"
"log"
"fmt"
)
// golang 第九天 学习 go web 编程
// 简单的go web server 可以通过net/http 包来实现
func Day09WebDemo() {
// 设置路由
http.HandleFunc("/", helloWorldPage)
// http server 监听端口
err := http.ListenAndServe(":9000", nil)
if err != nil {
log.Fatal(err)
}
}
func helloWorldPage(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // 解析表单
fmt.Println("请求的url", r.URL.Path)
fmt.Println("请求的表单", r.Form)
fmt.Println("请求的方法", r.Method)
fmt.Println("请求地址", r.Host)
fmt.Println("客户端地址", r.RemoteAddr)
for k, v := range r.Form{
fmt.Println(k)
fmt.Println(v)
}
fmt.Fprint(w, "Hello World")
}
上面的例子使用http.HandleFunc(), 指定了url 地址和 url 绑定的函数,使用http.ListenAndServe 指定了监听的端口, 我们将请求到 / 这个地址的绑定到了函数 helloWorldPage(), 需要注意的是,使用HandleFunc 绑定到的函数 必须要接收两个参数 http.ResponseWriter 和 http.Request, 我们通过 第二个参数 http.Request 就可以获取到各种请求的信息, 通过 http.ResponseWriter 给客户端响应
http处理表单数据
通过前面的例子我们知道了通过http.Request 可以获取到各种请求的信息,那当然也可以获取到用户POST的数据, 下面我们通过代码来学习获取表单的数据
func Day10WebForm() {
log.Println("Day10WebForm start")
// 将 /login 请求交给login 函数处理
http.HandleFunc("/login", login)
err := http.ListenAndServe(":8181", nil)
if err != nil {
fmt.Println("Startup Error, ", err)
}
}
// login ==================================================================
func login(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // 不执行这个 ParseForm 无法获取到表单数据
fmt.Println("Web Form: ", r.Form)
// method := r.Method
if len(r.Form) == 0 {
log.Println("Form Cannot Be Empty")
}
username := r.FormValue("username")
passwd := r.FormValue("password")
if username != "beer" {
fmt.Fprintln(w, "username Error")
}
if passwd != "123456" {
fmt.Fprintln(w, "password Error")
}
log.Println("login success!")
fmt.Fprintln(w, "200 OK")
}
这里我们通过FormValue的方法拿到表单的数据
http 处理文件上传
处理文件上传的思路就是拿到用户上传的文件,这里不再使用FormValue了 而是使用FormFile的方法,然后拿到文件的元数据,再写入文件即可
下面是文件上传的服务端demo 和 客户端的html 代码
服务端处理文件代码
package growth
import (
"net/http"
"fmt"
"os"
"io"
)
// golang 第十一天 学习 go web 编程 处理文件上传
func UploadHandler(w http.ResponseWriter, r *http.Request) {
// 处理文件上传
method := r.Method
if method == "POST" {
/*
处理文件上传我们需要调用r.ParseMultipartForm,里面的参数表示maxMemory,调用ParseMultipartForm之后,
上传的文件存储在maxMemory大小的内存里面,如果文件大小超过了maxMemory,那么剩下的部分将存储在系统的临时文件中。
我们可以通过r.FormFile获取上面的文件句柄
*/
r.ParseMultipartForm(4096)
file, handler, err := r.FormFile("upload")
if err != nil {
fmt.Println("FormFile Error", err)
}
fmt.Println("正在上传", handler.Filename)
defer file.Close()
// 服务端打开一个文件 以便将客户端上传的文件写入到该文件
fd, e := os.OpenFile("./" + handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if e != nil {
fmt.Println("Write File Error")
}
// 写入文件
io.Copy(fd, file)
defer fd.Close()
fmt.Fprintln(w, "200 OK Upload success! ", handler.Filename)
}
}
func Day11WebUploadFile() {
http.HandleFunc("/upload", UploadHandler)
err := http.ListenAndServe(":8182", nil)
if err != nil {
fmt.Println("文件上传失败", err)
}
}
客户端html 上传文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传</title>
</head>
<body>
<form enctype="multipart/form-data" action="http://127.0.0.1:8182/upload" method="post">
<input type="file" name="upload" />
<input type="submit" value="上传" />
</form>
</body>
</html>