go web

http请求

hello world

package main

import (
    "fmt"
    "net/http"
)

//创建处理器函数
func handler(w http.ResponseWriter,r *http.Request){
    //r.URL.Path路由中的参数
    fmt.Fprintln(w,"世界 你好",r.URL.Path)
}

func main(){
    //创建多路复用器
    mux:=http.NewServeMux()
    mux.HandleFunc("/",handler)
    //创建路由
    http.ListenAndServe(":8080",mux)

}
View Code

web服务器的创建

使用默认的多路复用器(DefaultServeMux)

1.使用处理器函数处理请求
package main

import (
    "fmt"
    "net/http"
)

//使用默认的多路服用器
//1.使用处理器函数处理请求
//创建处理器函数
func handler(w http.ResponseWriter,r *http.Request){
    fmt.Fprintln(w,"正在通过处理器函数处理您的请求")
}

func main(){
    http.HandleFunc("/",handler)
    http.ListenAndServe(":8080",nil)
}
View Code
2.使用处理器处理请求
package main

import (
    "fmt"
    "net/http"
)

//2.使用处理器处理请求

type MyHandler struct{}

func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "正在通过处理器处理您的请求")
}

func main() {
    myHandler := MyHandler{}
    //调用处理器
    http.Handle("/", &myHandler)
    http.ListenAndServe(":8080", nil)
}
View Code

3.测试通过Server结构详细配置服务器

package main

import (
    "fmt"
    "net/http"
    "time"
)

//通过Server结构对服务器进行更详细的配置

type MyHandler struct{}

func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "测试通过Server结构详细配置服务器")
}

func main() {
    myHandler := MyHandler{}
    //通过Server结构对服务器进行更详细的配置
    server := http.Server{
        Addr:        ":8080",
        Handler:     &myHandler,
        ReadTimeout: 2 * time.Second,
    }
    server.ListenAndServe()
}
View Code

使用自己创建的多路复用器

package main

import (
    "fmt"
    "net/http"
)

//使用自己创建的多路复用器

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "通过自己创建的多路复用器来处理请求")
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/myMux", handler)
    http.ListenAndServe(":8080", mux)
}
View Code

 

 数据库

model/user.go

package model

import (
    "fmt"
    "gotest/web02_db/utils"
)

//user结构体
type User struct {
    ID       int
    Username string
    Password string
    Email    string
}

//AddUser 添加User的方法一
func (user *User) AddUser1() error {
    //1.写sql语句
    sqlStr := "insert into users(username,password,email) values(?,?,?)"
    //2.预编译
    inStmt, err := utils.Db.Prepare(sqlStr)
    if err != nil {
        fmt.Println("预编译出现异常:", err)
        return err
    }

    //3.执行
    _, err2 := inStmt.Exec("admin", "123456", "admin@123.com")
    if err2 != nil {
        fmt.Println("执行出现异常:", err2)
        return err
    }
    return nil
}

//AddUser2 天机user的方法2
func (user *User) AddUser2() error {
    //1.写sql语句
    sqlStr := "insert into users(username,password,email) values(?,?,?)"
    //2.执行
    _, err := utils.Db.Exec(sqlStr, "admin2", "666666", "admin2@sina.com")
    if err != nil {
        fmt.Println("执行出现异常:", err)
        return err
    }
    return nil
}

func (user *User) AddUser() error {
    //写sql语句
    sqlStr := "insert into users(username,password,email) values(?,?,?)"
    //预编译
    stmt, err := utils.Db.Prepare(sqlStr)
    if err != nil {
        fmt.Println("预编译出现异常:", err)
        return err
    }
    //执行
    _, erro := stmt.Exec(user.Username, user.Password, user.Email)
    if erro != nil {
        fmt.Println("执行出现异常:", erro)
        return erro
    }
    return nil
}

//获取一条记录
func (user *User) GetUserByID(userId int) (*User, error) {
    //写sql语句
    sqlStr := "select id,username,password,email from users where id=?"
    //执行sql
    row := utils.Db.QueryRow(sqlStr, userId)
    //声明三个变量
    var username string
    var password string
    var email string
    //将各个字段中的值读取到以上三个变量中
    err := row.Scan(&userId, &username, &password, &email)
    if err != nil {
        return nil, err
    }
    //将三个变量的值赋给User结构体
    u := &User{
        ID:       userId,
        Username: username,
        Password: password,
        Email:    email,
    }
    return u, nil
}

//获取多条记录
func (user *User) GetUsers() ([]*User, error) {
    //写sql语句
    sqlStr := "select id,username,password,email from users"
    //执行sql
    rows, err := utils.Db.Query(sqlStr)
    if err != nil {
        return nil, err
    }
    //定义一个User切片
    var users []*User
    //遍历
    for rows.Next() {
        var userID int
        var userename string
        var password string
        var email string
        //将各个字段的值读取到以上三个变量中
        err := rows.Scan(&userID, &user.Username, &password, &email)
        if err != nil {
            return nil, err
        }
        //将三个变量的值赋给User结构体
        u := &User{
            ID:       userID,
            Username: userename,
            Password: password,
            Email:    email,
        }
        //将u添加到users切片中
        users = append(users, u)
    }
    return users, nil

}
View Code

model/test_user.go

package model

import (
    "fmt"
    "testing"
)

//TestMain函数可以再测试是函数之前做一些其他的操作

func TestMain(m *testing.M) {
    fmt.Println("测试开始:")
    //通过m.Run()来执行测试函数
    m.Run()
}

/*
如果一个测试函数的函数名的不是以 Test 开头,那么在使用 go test 命令时默
认不会执行,不过我们可以设置该函数时一个子测试函数,可以在其他测试函
数里通过 t.Run 方法来执行子测试函数,具体代码如下
*/

func TestUser(t *testing.T) {
    fmt.Println("开始测试user中相关方法")
    //通过t.Run()来执行子测试函数
    t.Run("测试添加用户:", testAddUser)
    t.Run("正在测试获取一个用户:", testGetUserID)
}

//子测试函数
//如果函数名不是以Test开头的那吗函数默认不执行,我们可以将它设置为一个子测试函数
func testAddUser(t *testing.T) {
    fmt.Println("子测试函数执行")
    user := &User{
        Username: "admin5",
        Password: "123456",
        Email:    "admin5@124.com",
    }
    //将user添加到数据库中
    user.AddUser()
}

//子测试函数
//获取一条记录
func testGetUserID(t *testing.T) {
    u := &User{}
    user, _ := u.GetUserByID(1)
    fmt.Println("用户的信息是:", *user)
}

//在user_test.go中测试添加员工的方法
func TestAddUser(t *testing.T) {
    user := &User{
        Username: "admin4",
        Password: "123",
        Email:    "admins4@11.com",
    }
    //将user添加到数据库中
    user.AddUser()
}

//获取所有数据
View Code

util/db.go

package utils

import (
    "database/sql"
    _"github.com/go-sql-driver/mysql"
)

var (
    Db  *sql.DB
    err error
)

func init() {
    Db, err = sql.Open("mysql", "root:root@tcp(localhost:3306)/test")
    if err != nil {
        panic(err.Error())
    }
}
View Code

 请求 与响应

main.go

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

//创建处理器函数
func handler1(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "测试http协议")
    //获取内容长度
    length := r.ContentLength
    //创建一个字节切片
    body := make([]byte, length)
    //读取请求体
    r.Body.Read(body)
    fmt.Fprintln(w, "请求体中的内容:", string(body))

}

//创建处理器函数
func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "测试http协议")
    //解析表单
    r.ParseForm()
    //获取请求参数
    //在r.Form之前一定要调用rParseForm
    fmt.Fprintln(w, "请求参数:", r.Form)
    //请求参数: map[password:[67889] username:[admin]]
}

//PostForm,只获取表单中的参数
func handler3(w http.ResponseWriter, r *http.Request) {
    //解析表单
    r.ParseForm()
    //获取请求参数
    //如果enctype属性值为multipart/form-data
    //需要使用MultipartForm字段
    fmt.Fprintln(w, "请求参数为:", r.PostForm)
    //请求参数为: map[password:[999] username:[jack]]
}

//直接获取请求参数
func handler4(w http.ResponseWriter, r *http.Request) {
    //获取请求参数
    fmt.Fprintln(w, "请求参数username的值为。", r.FormValue("username"))
    //请求参数username的值为。 rose
}

//直接获取请求参数
func handler5(w http.ResponseWriter, r *http.Request) {
    //获取请求参数
    fmt.Fprintln(w, "请求参数username的值为。", r.PostFormValue("username"))
    //请求参数username的值为。 rose
}

// r.FormValue

//处理上传文件
func handler6(w http.ResponseWriter, r *http.Request) {
    //解析表单
    r.ParseMultipartForm(1024)
    //打印表单数据
    fmt.Fprintln(w, r.MultipartForm)
    //&{map[username:[kkk]] map[photo:[0xc000100000]]}

}

//打开上传文件,显示
func handler7(w http.ResponseWriter, r *http.Request) {
    //解析表单
    r.ParseMultipartForm(1024)
    fileHeader := r.MultipartForm.File["photo"][0]
    file, err := fileHeader.Open()
    if err == nil {
        data, err := ioutil.ReadAll(file)
        if err == nil {
            fmt.Fprintln(w, string(data))
        }
    }

}

//net/http 提供的 FormFile 方法可以快速的获取被上传的文件,但是只能处理上
//传一个文件的情况
func handler8(w http.ResponseWriter, r *http.Request) {
    file, _, err := r.FormFile("photo")
    if err == nil {
        data, err := ioutil.ReadAll(file)
        if err == nil {
            fmt.Fprintln(w, string(data))
        }
    }

}

/*
响应部分
客户端响应
*/

func handler9(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("你的请求我已经收到"))
}

//给客户端响应一个html页面
//处理器中的代码
func handler10(w http.ResponseWriter, r *http.Request) {
    html := `
<html>
<head>
<title>测试响应内容为网页</title>
<meta charset="utf-8" />
</head>
<body>
我是以网页的形式响应过来的!
</body>
</html>
`
    w.Write([]byte(html))
}

//user结构体
type User struct {
    ID       int
    Username string
    Password string
}

//给客户端响应json格式数据
func handler11(w http.ResponseWriter, r *http.Request) {
    //设置响应头中内容的类型
    w.Header().Set("Content-Type", "application/json")
    user := User{
        ID:       1,
        Username: "admin",
        Password: "123456",
    }
    //将user转换为json格式
    json, _ := json.Marshal(user)
    w.Write(json)
}

//让客户端重定向
func handler12(w http.ResponseWriter, r *http.Request) {
    //一下操作必须要在WriteHeader之前执行
    w.Header().Set("Location", "https://www.baidu.com")
    w.WriteHeader(302)
}

func main() {
    http.HandleFunc("/getBody", handler4)
    http.HandleFunc("/upload", handler8)
    //响应部分
    http.HandleFunc("/res", handler12)
    //路由
    http.ListenAndServe(":8080", nil)
}
View Code

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/getBody?username=admin&pwd=123" method="post">
    用户名:<input type="text" name="username"/><br/>
    密码:<input type="password" name="password"/><br/>
    <input type="submit">

</form>
<br>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username"/><br/>
    文件:<input type="file" name="photo"/><br/>
    <input type="submit">

</form>
</body>
</html>
View Code

模板

package main

import (
    "html/template"
    "math/rand"
    "net/http"
    "time"
)

func handler(w http.ResponseWriter, r *http.Request) {
    //解析模板文件
    t := template.Must(template.ParseFiles("hello.html"))
    //声明一个变量
    age := 16
    //执行模板
    t.Execute(w, age > 18)
}

//迭代动作
func handler1(w http.ResponseWriter, r *http.Request) {
    //解析模板文件
    t := template.Must(template.ParseFiles("hello1.html"))
    //声明一个字符串切片
    stars := []string{"jack", "roe", "baihe"}
    //执行模板
    t.Execute(w, stars)
}

//
func handler2(w http.ResponseWriter, r *http.Request) {
    //解析模板文件
    t := template.Must(template.ParseFiles("hello2.html"))
    //执行模板
    t.Execute(w, "狸猫")
}

//包含

//
func handler3(w http.ResponseWriter, r *http.Request) {
    //解析模板文件
    t := template.Must(template.ParseFiles("hello3.html", "hello3_ext.html"))
    //执行模板
    t.Execute(w, "测试包含")
}

//同一个模板文件内定义
//定义动作
func handler4(w http.ResponseWriter, r *http.Request) {
    //解析模板文件
    t := template.Must(template.ParseFiles("hello4.html"))
    //执行模板
    t.ExecuteTemplate(w, "model", "")
}

//从其他文件包含

func handler5(w http.ResponseWriter, r *http.Request) {
    rand.Seed(time.Now().Unix())
    var t *template.Template
    if rand.Intn(5) > 2 {
        //解析模板文件
        t = template.Must(template.ParseFiles("hello5.html", "hello5_content1.html"))
    } else {
        //解析模板文件
        t = template.Must(template.ParseFiles("hello5.html", "hello5_content2.html"))
    }
    //执行模板
    t.ExecuteTemplate(w, "model", "")
}

//块动作

func handler6(w http.ResponseWriter, r *http.Request) {
    rand.Seed(time.Now().Unix())
    var t *template.Template
    if rand.Intn(5) > 2 {
        //解析模板文件
        t = template.Must(template.ParseFiles("hello6.html",
            "hello6_content1.html"))
    } else {
        //解析模板文件
        t = template.Must(template.ParseFiles("hello6.html"))
    }
    //执行模板
    t.ExecuteTemplate(w, "model", "")
}

func main() {
    http.HandleFunc("/t", handler)
    http.HandleFunc("/t1", handler1)
    http.HandleFunc("/t2", handler2)
    http.HandleFunc("/t3", handler3)
    http.HandleFunc("/t4", handler4)
    http.HandleFunc("/t5", handler5)
    http.HandleFunc("/t6", handler6)
    //路由
    http.ListenAndServe(":8080", nil)
}
View Code

 cookie

package main

import (
    "fmt"
    "net/http"
)

//cookie使用
func handler1(w http.ResponseWriter, r *http.Request) {
    cookie1 := http.Cookie{
        Name:     "user1",
        Value:    "admin",
        HttpOnly: true,
    }
    cookie2 := http.Cookie{
        Name:     "user2",
        Value:    "superAdmin",
        HttpOnly: true,
    }

    //将Cookie发送给浏览器,几天假第一个Cookie
    w.Header().Set("Set-Cookie", cookie1.String())
    //再添加一个Cookie
    w.Header().Add("Set-Cookie", cookie2.String())

}

//方式二设置cookie
func handler2(w http.ResponseWriter, r *http.Request) {
    cookie1 := http.Cookie{
        Name:     "user1",
        Value:    "admin",
        HttpOnly: true,
    }
    cookie2 := http.Cookie{
        Name:     "user2",
        Value:    "admin2",
        HttpOnly: true,
    }

    //设置cookie
    http.SetCookie(w, &cookie1)
    http.SetCookie(w, &cookie2)

}

//读取cookie
func handler3(w http.ResponseWriter, r *http.Request) {
    //获取请求头中的Cookie
    cookies := r.Header["Cookie"]
    fmt.Fprintln(w, cookies)
}

//设置失效时间
func handler4(w http.ResponseWriter, r *http.Request) {
    cookie := http.Cookie{
        Name:     "user",
        Value:    "perisistAdmin",
        HttpOnly: true,
        MaxAge:   60,
    }
    //将cokkie发送给浏览器
    w.Header().Set("Set-Cookie", cookie.String())
}
func main() {

    http.HandleFunc("/c1", handler1)
    http.HandleFunc("/c2", handler2)
    http.HandleFunc("/c3", handler3)
    http.HandleFunc("/c4", handler4)


    //路由
    http.ListenAndServe(":8080", nil)
}
View Code

 

未完待续。。。

posted @ 2020-02-24 11:26  jiuchen  阅读(378)  评论(0编辑  收藏  举报