go语言web开发01 - 之go原生的web-server开发

go语言里自带的net/http包提供了http客户端和服务端的实现,也就是说go语言原生支持web服务开发,下面我们来看一下go原生的http服务端实现吧

 

一、go简单实现web Server

1.1、代码部分

package main

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

// 定义url路径对应的处理函数
func Hello(w http.ResponseWriter, r *http.Request) {
    fmt.Println("handle Hello")      // 后台输出的信息
    fmt.Fprintf(w, "hello")   // 响应请求的数据
}

// 定义url路径对应的处理函数
func login(w http.ResponseWriter, r *http.Request) {
    fmt.Println("handle Hello")     // 后台输出的信息
    // fmt.Fprintf(w, "login")            // 响应请求的数据
    io.WriteString(w, "response data")     // 也可以使用io包下的方法返回消息
}

func main() {
    // 1.定义url路径与url路径对应的处理函数
    http.HandleFunc("/", Hello)
    http.HandleFunc("/user/login", login)

    // 2.设置http监听
    err := http.ListenAndServe("0.0.0.0:8088", nil)
    if err != nil {
        fmt.Println("http listen failed:", err)
    }
}

1.2、请求展示

1.请求/路径

 

2.请求/user/login路径

 

 

 

 二、http客户端实现

package main

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

func main() {
    // 发送http GET请求
    ret, err := http.Get("https://www.baidu.com")        
    if err != nil {      // 错误处理
        fmt.Println("get url err:",err)
        return
    }
    // 利用ioutil.ReadAll方法读取返回结果里的Body内容
    data, err := ioutil.ReadAll(ret.Body)      
    if err != nil {       // 错误处理
        fmt.Println("get data err:",err)
        return
    }
    fmt.Println(string(data))      // 打印最终结果

}

 

三、网站检测

package main

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

// http head检测

var url = []string{
    "https://www.baidu.com",
    "http://www.taobao.com",
    "https://www.uxuan.cc",
    "https://google.com",
}

func main() {
    for _,v := range url {        // 1.循环获取url

        c := http.Client{          // 2.自己生成http客户端
            Transport: &http.Transport {        // (语法是固定的,记住怎么用就可以了)
                Dial: func(network, addr string) (net.Conn, error) {
                    timeout := time.Second * 2         // 3.设置请求超时时间,超过两秒就退出请求
                    return net.DialTimeout(network, addr, timeout)
                },
            },
        }

        resp, err := c.Head(v)       // 4.http.head请求循环获取到的url
        if err != nil {
            fmt.Printf("head %s failed, err:%v\n",v,err)
            continue
        }
        fmt.Printf("head succ, status:%v\n",resp.Status)         // 5.打印http状态吗
    }
}

 

四、web server模板示例

1.服务端代码部分

package main

import (
    "fmt"
    "text/template"
    "net/http"

)

// 定义模板变量
var myTemplate *template.Template

// 定义结构体
type Person struct {       
    Name string
    Age  int
}

// 处理请求的函数(http.ResponseWriter:为响应数据的值。 *http.Request:为接受请求的参数)
func index(w http.ResponseWriter, r *http.Request) {
    // 初始化结构体
    p := Person{Name: "Dream", Age: 10}
    // 模板文件作用在哪里,p为往模板文件里传的变量
    myTemplate.Execute(w, p)
    // myTemplate.Execute(os.Stdout, p)        // 支持将模板作用到终端、文件或者其他的地方
}

// 初始化模板文件的函数
func initTemplate(filename string) (err error) {
    // 通过template.ParseFiles初始化模板文件,获得一个初始化后的模板文件和err
    myTemplate, err = template.ParseFiles(filename)
    if err != nil {    // 判断错误并返回错误
        fmt.Println("parse templatefile err:",err)
        return
    }
    return 
}

func main() {
    // 调用初始化模板文件的函数初始化模板文件
    initTemplate("E:/Scripts/go/src/go_dev/day10/5_wen-template/main/index.html")
    // 请求url与处理请求的函数指定
    http.HandleFunc("/index", index)
    // 监听端口
    err := http.ListenAndServe("0.0.0.0:8888", nil)
    if err != nil {
        fmt.Println("http listen failed")
    }
}

 

2.模板内容

<html>
    <head>
        <title>My GoLang Test Package</title>
            <body>
                <h1>标题</h1>
                {{if gt .Age 18}}
                <p>your age big 18</p>
                {{else}}
                <p>your age min 18</p>
                {{end}}
                <p>Hell, {{.Name}}</p>     <!-- .代表当前的p标签 -->
            </body>
    </head>
</html>

 

3.模板里的一些其他操作

1.    not 非 {{if not .condition}} 代码 {{end}}
    2.    and 与 {{if and .condition1 .condition2}} 代码 {{end}}
    3.    or 或 {{if or .condition1 .condition2}} 代码 {{end}} 
    4.    eq 等于 {{if eq .var1 .var2}} 代码 {{end}} 
    5.    ne 不等于 {{if ne .var1 .var2}} 代码 {{end}} 
    6.    lt 小于 (less than) {{if lt .var1 .var2}} 代码 {{end}} 
    7.    le 小于等于 {{if le .var1 .var2}} 代码 {{end}} 
    8.    gt 大于 {{if gt .var1 .var2}} 代码 {{end}} 
    9.    ge 大于等于 {{if ge .var1 .var2}} 代码 {{end}}
    10.with
        <html>
        <head>
        </head>
        <body>
            {{with .Name}}
                <p>hello, old man, {{.}}</p>
            {{end}}
        </body>
        </html>

 

4.访问模板

 

 

 

五、http from表单示例

package main
import (
    "io"
    "net/http"
    "log"
)

// 通过const定义一个form表单的常量
const form = `<html><body><form action="#" method="post" name="bar">
                    <input type="text" name="in"/>
                    <input type="text" name="in"/>
                     <input type="submit" value="Submit"/>
             </form></body></html>`

// SimpleServer 函数 ,http.ResponseWriter:响应请求 , http.Request:接收请求
func SimpleServer(w http.ResponseWriter, request *http.Request) {
    io.WriteString(w, "<h1>hello, world</h1>")          // 响应的数据为:"<h1>hello, world</h1>"
    panic("url: /test1, func: SimpleServer, failed !!")      // panic捕获
}

// FormServer函数
func FormServer(w http.ResponseWriter, request *http.Request) {
    w.Header().Set("Content-Type", "text/html")        // w.Header().Set()设置响应的head信息
    switch request.Method {         // 通过switch语句判断http请求的方法
    case "GET":           // 如果是GET方法
        io.WriteString(w, form)      // 返回上面定义的form表单
    case "POST":          // 如果是post方法
        request.ParseForm()      // 通过request.ParseForm()来解析表单
        io.WriteString(w, request.Form["in"][0])       // 获取表单里的name为in的下标是0的参数(获取的格式是数组)
        io.WriteString(w, "\n")        // 设置换行
        io.WriteString(w, request.FormValue("in"))       // 获取表单里name为in的值(推荐用这种获取form值得方法)
    }
}
func main() {
    http.HandleFunc("/test1", logPanics(SimpleServer))       // 如果请求的是 ip:port/test1就指定SimpleServer函数处理(logPanics()为处理panic的函数)
    http.HandleFunc("/test2", logPanics(FormServer))       // 如果请求的是 ip:port/test2就指定FormServer函数处理
    if err := http.ListenAndServe(":8088", nil); err != nil {          // 监听端口
    }
}

// panic处理(防止其中一个函数出错影响其他得处理请求得函数)
func logPanics(handle http.HandlerFunc) http.HandlerFunc {       // 接收参数为处理请求得函数,返回值也是处理请求得函数
    return func(writer http.ResponseWriter, request *http.Request) {
        defer func() {      // 返回之前执行defer方法
            if x := recover(); x != nil {       // 处理recover()
                log.Printf("[%v] caught panic: %v", request.RemoteAddr, x)
            }
        }()
        handle(writer, request)      // 调用传进来得函数,即真正处理请求得函数
    }
}

 

posted @ 2020-08-23 14:48  欧-阳  阅读(999)  评论(0)    收藏  举报