GO_HTTP

GO原生支持http, import("net/http")

package main

import (
	"fmt"
	"net/http"
)

func Hello(w http.ResponseWriter, r *http.Request){
	fmt.Println("handle hello")
	fmt.Fprintf(w, "hello") // 向响应写入内容
}

func main(){
	http.HandleFunc("/", Hello) // 路由对应关系
	err := http.ListenAndServe("127.0.0.1:8000", nil) // 监听IP端口
	if err != nil{
		fmt.Println("http listen failed")
	}

}

访问一个网络地址

get请求

package main

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

func main(){
        // 文件
	file, err := os.OpenFile("aa.jpg", os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil{
		fmt.Println("file err", err)
	}
	defer file.Close()
	bufferWriter := bufio.NewWriter(file)

        // 请求
	imf_url :=`http://pic.58pic.com/58pic/13/74/51/99d58PIC6vm_1024.jpg`
	res, err := http.Get(imf_url) // 请求地址
	if err != nil{
		fmt.Println("get err:", err)
		return 
	}
	data, err := ioutil.ReadAll(res.Body) // 
	if err != nil{
		fmt.Println("data err:",err)
		return
	}
	_, err = bufferWriter.Write(data)
	bufferWriter.Flush()
	
}

head请求

package main

import (
	"fmt"
	"net/http"
	"time"
	"net"
	// "io/ioutil"
	// "os"
	// "bufio"
)

// func main(){
// 	var url = []string{
// 		"https://www.baidu.com/",
// 		"http://google.com",
// 		"http://taobao.com",
// 	}

// 	for _, v := range url{
// 		rep, err := http.Head(v)
// 		if err != nil{
// 			fmt.Printf("head %s failesd, err: %v\n", v, err)
// 			continue
// 		}
// 		fmt.Printf("head succ status%v\n", rep.Status) 
// 	}
// }

//设置超时时间

func main(){
	var url = []string{
		"https://www.baidu.com/",
		"http://google.com",
		"http://taobao.com",
	}
	c := http.Client{
		Transport: &http.Transport{
			Dial:func(network, addrs string)(net.Conn, error){
				timeout := time.Second*2
				return net.DialTimeout(network, addrs, timeout)
			},
		},
	}
	for _, v := range url{
		rep, err := c.Head(v)
		if err != nil{
			fmt.Printf("head %s failesd, err: %v\n", v, err)
			continue
		}
		fmt.Printf("head succ status%v\n", rep.Status) 
	}
}

源码浅析

// http下
func Head(url string) (resp *Response, err error) {
	return DefaultClient.Head(url)
}

// 使用了一个默认的连接去执行指定的方法
var DefaultClient = &Client{}

// 在Client结构体中, Transport定义了连接使用的机制, 他是一个接口定义了RoundTrip(*Request) (*Response, error)方法

// http.Transport是实现了该接口的, 其中的Dial是创建连接的一个函数network, addr分别是连接类型和地址

// net.DialTimeout返回一个有超时时间的连接

请求头和请求类型

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 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() // 先要解析这个表单
		io.WriteString(w, request.Form["in"][0]) // 方式一取到input的值是个列表
		io.WriteString(w, "\n")
		io.WriteString(w, request.FormValue("in"))// 取到一个, 这两个的区别就像Django中request的value和value_list
	}
}
func main() {
	http.HandleFunc("/test2", FormServer)
	if err := http.ListenAndServe(":8088", nil); err != nil {
	}
}

  使用装饰器来处理异常

func main() {
	http.HandleFunc("/test1", logPanics(SimpleServer))
	http.HandleFunc("/test2", logPanics(FormServer))
	if err := http.ListenAndServe(":8088", nil); err != nil {
	}
}

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)
	}
}

模板

package main

import (
	"fmt"
	"os"
	"text/template" // 导入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())
	}
}

模板语法

{{.}} // 表示传进去的变量
{{.attr}} // 取属性

{{ if gt .Age 18}} gt 大于
// 逻辑操作符
// not 
// and 
// or 
// 更多比较操作符
// eq 等于 
// ne 不等于 
// lt 小于
// le 小于等于
// gt 大于
// ge 大于等于
{{else}}
{{end}}

// 循环一个可循环的结构
{{range .}}
{{end}}

  

posted @ 2018-09-22 16:44  瓜田月夜  阅读(268)  评论(0)    收藏  举报