Golang网络编程二 http

Golang的http包功能非常完善,提供了HTTP客户端和服务端的实现。支持Get、Head、Post和PostForm函数发出HTTP/ HTTPS请求,HTTP Head的设置。

简单的http客户端demo,即客户端请求服务端

package main

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

func main() {
	resp, err := http.Get("http://www.baidu.com")
	if err != nil {
		fmt.Fprint(os.Stdout,err)
	}
	defer resp.Body.Close()
	bytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Fprint(os.Stdout,err)
	}
	fmt.Println("返回打印结果:", string(bytes))
}

上面的代码是将百度作为服务端,由本地发起请求,将百度返回内容打印输出。

简单的http服务端demo

package main

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

func httpHandleFun(w http.ResponseWriter, r *http.Request)  {
	io.WriteString(w,"Hello Web")
}

func main() {
	http.HandleFunc("/hello", httpHandleFun)
	serve := http.ListenAndServe("localhost:8080", nil)
	if serve != nil {
		log.Fatal(serve)
	}
}

代码种http.HandleFunc(),该方法用于分发请求,即针对某一路径请求将其映射到指定的业务逻辑处理方法中。

上例中,我们在浏览器地址栏输入:http://localhost:8080/hello

浏览器页面输出:Hello Web

我们第一个http程序就成功了。

我们现在使用一个完整的示例,来练习Golang的http编程。

这个demo的功能包括:

1、图片上传

2、上传后跳转到图片查看页面

3、图片上传列表页面

package main

import (
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

/**
	图片上传
 */
func uploadHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		io.WriteString(w, "<html><body><form method=\"POST\" action=\"http://localhost:8080/upload\" "+
			" enctype=\"multipart/form-data\">"+
			"Choose an image to upload: <input name=\"image\" type=\"file\" />"+
			"<input type=\"submit\" value=\"Upload\" />"+
			"</form></body></html>")
		return
	}

	if r.Method == "POST" {
		log.Println("post")
		file, header, e := r.FormFile("image")
		if e != nil {
			log.Fatal(e)
			return
		}
		s := header.Filename
		create, e := os.Create("d:/images/" + s)
		defer create.Close()
		if e != nil {
			log.Fatal(e)
			return
		}
		_, e = io.Copy(create, file)
		if e != nil {
			log.Fatal(e)
			return
		}
		http.Redirect(w,r,"/view?id="+s,http.StatusFound)
	}
}

/**
	图片显示
 */
func viewHandler(w http.ResponseWriter, r *http.Request)  {
	value := r.FormValue("id")
	imagePath := "d://images/" + value
	if isExist(imagePath) {
		w.Header().Set("Content-Type","image")
		http.ServeFile(w,r, imagePath)
	} else {
		http.NotFound(w,r)
	}
}

func isExist(name string) bool {
	_, e := os.Stat(name)
	if e != nil {
		return false
	} else {
		return true
	}
}

func listHandle(w http.ResponseWriter, r *http.Request)  {
	infos, e := ioutil.ReadDir("d:/images/")
	if e != nil {
		log.Fatal("查看列表出错:",e)
	}
	var listHtml string
	for _,fi := range infos {
		listHtml += "<li><a href=\"/view?id="+ fi.Name() +"\"> "+ fi.Name() +" </a></li>"
	}
	listHtml = "<html><body><ol>"+ listHtml +"</ol></body></html>"
	io.WriteString(w,listHtml)
	return
}

func main() {
	log.Println("main start")
	http.HandleFunc("/view", viewHandler)
	http.HandleFunc("/upload", uploadHandler)
	http.HandleFunc("/list", listHandle)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err.Error())
	}
	log.Println("main end")
}