http/模板

a. Go原生支持http,import(“net/http”)
b. Go的http服务性能和nginx比较接近
c. 几行代码就可以实现一个web服务
http常见请求方法
1)Get请求
2)Post请求
3)Put请求
4)Delete请求
5)Head请求

http示例:

package main

import (
    "fmt"
    "net/http"
)

func Hello(w http.ResponseWriter, r *http.Request) {
    //服务端输出
    fmt.Println("handle hello")
    //浏览器输出
    fmt.Fprintf(w, "hello ")
}

func Login(w http.ResponseWriter, r *http.Request) {
    //服务端输出
    fmt.Println("handle login")
    //浏览器输出
    fmt.Fprintf(w, "login ")
}

func main() {
    http.HandleFunc("/", Hello)
    http.HandleFunc("/login", Login)
    err := http.ListenAndServe("0.0.0.0:8080", nil)
    if err != nil {
        fmt.Println("http listen failed")
    }
}

客户端

package main

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

func main() {
    res, err := http.Get("https://www.baidu.com/")
    if err != nil {
        fmt.Println("get err:", err)
        return
    }

    data, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println("get data err:", err)
        return
    }

    fmt.Println(string(data))
}

head请求实例:

package main

import (
    "fmt"
    "net/http"
)

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

func main() {

    for _, v := range url {
        resp, err := http.Head(v)
        if err != nil {
            fmt.Printf("head %s failed, err:%v\n", v, err)
            continue
        }

        fmt.Printf("head succ, status:%v\n", resp.Status)
    }
}

输出:
head succ, status:200 OK
head http://google.com failed, err:Head http://google.com: dial tcp 172.217.160.78:80: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
head succ, status:200 OK

还可以自己设置过期时间:

package main

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

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

func main() {

    for _, v := range url {
        c := http.Client{
            Transport: &http.Transport {
                Dial:func(network, addr string) (net.Conn, error){
                    //自己设置超时时间
                    timeout := time.Second*2
                    return net.DialTimeout(network, addr, timeout)
                },
        },
        }
        resp, err := c.Head(v)
        if err != nil {
            fmt.Printf("head %s failed, err:%v\n", v, err)
            continue
        }

        fmt.Printf("head succ, status:%v\n", resp.Status)
    }
}

http 常见状态码:

http.StatusContinue = 100
http.StatusOK = 200
http.StatusFound = 302
http.StatusBadRequest = 400
http.StatusUnauthorized = 401
http.StatusForbidden = 403
http.StatusNotFound = 404
http.StatusInternalServerError = 500


表单处理(此例两个input的name都是in,注意:w, request.Form["in"][0],很显然是个数组):

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

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></html></body>`

func SimpleServer(w http.ResponseWriter, request *http.Request) {
    io.WriteString(w, "<h1>hello, world</h1>")
}

func FormServer(w http.ResponseWriter, request *http.Request) {
    w.Header().Set("Content-Type", "text/html")
    switch request.Method {
    case "GET":
        io.WriteString(w, form)
    case "POST":
        request.ParseForm()
        //此处获取第一个in输入框数据
        io.WriteString(w, request.Form["in"][0])
        io.WriteString(w, "\n")
        //此处获得的也是第一个in输入框的数据
        io.WriteString(w, request.FormValue("in"))
    }
}
func main() {
    http.HandleFunc("/test1", SimpleServer)
    http.HandleFunc("/test2", FormServer)
    if err := http.ListenAndServe(":8088", nil); err != nil {
    }
}

panic处理(注意类型):

package main

import (
    "log"
    "net/http"
)

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></html></body>`

//代码省略
func main() {
    http.HandleFunc("/test1", logPanics(SimpleServer))
    http.HandleFunc("/test2", logPanics(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() {
            if x := recover(); x != nil {
                log.Printf("[%v] caught panic: %v", request.RemoteAddr, x)
            }
        }()
        handle(writer, request)
    }
}

go自己支持模板:
go文件:

package main

import (
    "fmt"
    "os"
    "text/template"
)

type Person struct {
    Name string
    // 1.注意此处的大小写和模板中的大小写一致
    // 2.注意Age的类型要是数字类型才能在模板中比大小
    Age  int
}

func main() {
    t, err := template.ParseFiles("./index.html")
    if err != nil {
        fmt.Println("parse file err:", err)
        return
    }
    p := Person{Name: "Mary", Age: 31}
    //这里只是输出在终端,如果输出在浏览器,就用w http.ResponseWriter
    if err := t.Execute(os.Stdout, p); err != nil {
        fmt.Println("There was an error:", err.Error())
    }
}

html文件:

<html>
<head></head>
<body>
    {{if gt .Age 18}}
        <p>hello, old man, {{.Name}}</p>
    {{else}}
        <p>hello,young man, {{.Name}}</p>
    {{end}}

    {{/*.代表go文件中的p*/}}
    {{.}}
</body>
</html>

http版模板:

package main

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

var myTemplate *template.Template

type Result struct {
    output string
}

func (p *Result) Write(b []byte) (n int, err error) {
    fmt.Println("called by template")
    p.output += string(b)
    return len(b), nil
}

type Person struct {
    Name  string
    Title string
    Age   int
}

func userInfo(w http.ResponseWriter, r *http.Request) {
    fmt.Println("handle hello")
    //fmt.Fprintf(w, "hello ")
    var arr []Person
    p := Person{Name: "Mary001", Age: 10, Title: "我的个人网站"}
    p1 := Person{Name: "Mary002", Age: 10, Title: "我的个人网站"}
    p2 := Person{Name: "Mary003", Age: 10, Title: "我的个人网站"}
    arr = append(arr, p)
    arr = append(arr, p1)
    arr = append(arr, p2)

    resultWriter := &Result{}
    io.WriteString(resultWriter, "hello world")
    err := myTemplate.Execute(w, arr)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("template render data:", resultWriter.output)
    //myTemplate.Execute(w, p)
    //myTemplate.Execute(os.Stdout, p)
    //file, err := os.OpenFile("C:/test.log", os.O_CREATE|os.O_WRONLY, 0755)
    //if err != nil {
    //  fmt.Println("open failed err:", err)
    //  return
    //}

}

func initTemplate(filename string) (err error) {
    myTemplate, err = template.ParseFiles(filename)
    if err != nil {
        fmt.Println("parse file err:", err)
        return
    }
    return
}

func main() {
    initTemplate("d:/project/src/go_dev/day10/template_http/index.html")
    http.HandleFunc("/user/info", userInfo)
    err := http.ListenAndServe("0.0.0.0:8880", nil)
    if err != nil {
        fmt.Println("http listen failed")
    }
}

1)替换 {{.字段名}}

package main

import (
    "fmt"
    "os"
    "text/template"
)

type Person struct {
    Name string
    age  string
}

func main() {
    t, err := template.ParseFiles("./index.html")
    if err != nil {
        fmt.Println("parse file err:", err)
        return
    }
    p := Person{Name: "Mary", age: "31"}
    if err := t.Execute(os.Stdout, p); err != nil {
        fmt.Println("There was an error:", err.Error())
    }
}

1)if判断

<html>
        <head>
        </head>
        <body>
                {{if gt .Age 18}}
                <p>hello, old man, {{.Name}}</p>
                {{else}}
                <p>hello,young man, {{.Name}}</p>
                {{end}}
        </body>
</html>

2)if常见操作符:
• not 非{{if not .condition}} {{end}}
• and 与{{if and .condition1 .condition2}} {{end}}
• or 或{{if or .condition1 .condition2}} {{end}}
• eq 等于{{if eq .var1 .var2}} {{end}}
• ne 不等于{{if ne .var1 .var2}} {{end}}
• lt 小于 (less than){{if lt .var1 .var2}} {{end}}
• le 小于等于{{if le .var1 .var2}} {{end}}
• gt 大于{{if gt .var1 .var2}} {{end}}
• ge 大于等于{{if ge .var1 .var2}} {{end}}
3){{.}}:

<html>
        <head>
        </head>
        <body>
                <p>hello, old man, {{.}}</p>
        </body>
</html>

4){{with .Var}}
5){{end}}

<html>
        <head>
        </head>
        <body>
                {{with .Name}}
                <p>hello, old man, {{.}}</p>
                {{end}}
        </body>
</html>

6)循环,{{range.}} ,{{end }}

<html>
        <head>
        </head>
        <body>
                {{range .}}
                    {{if gt .Age 18}}
                    <p>hello, old man, {{.Name}}</p>
                    {{else}}
                    <p>hello,young man, {{.Name}}</p>
                    {{end}}
                {{end}}
        </body>
</html>

转载于:https://blog.51cto.com/5660061/2349748

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值