net/http
包,我们来看看它。我们从一些简单的示例开始, 首先编写一个“Hello world!”:查看示例15.6http
包并启动了网页服务器,和15.1的net.Listen("tcp", "localhost:50000")
函数的tcp服务器是类似的,使用http.ListenAndServe("localhost:8080", nil)
函数,如果成功会返回空,否则会返回一个错误(可以指定localhost为其他地址,8080是指定的端口号)http.URL
描述了web服务器的地址,内含存放了url字符串的Path
属性;http.Request
描述了客户端请求,内含一个URL
属性req
请求是一个POST类型的html表单,“var1”就是html表单中一个输入属性的名称,然后用户输入的值就可以通过GO代码:req.FormValue("var1")
获取到(请看章节15.4)。还有一种方法就是先执行request.ParseForm()
然后再获取request.Form["var1"]
的第一个返回参数,就像这样:found
就是true
,如果var1
并未出现在表单中,found
就是false
map[string][]string
类型。网页服务器返回了一个http.Response
,它是通过http.ResponseWriter
对象输出的,这个对象整合了HTTP服务器的返回结果;通过对它写入内容,我们就将数据发送给了HTTP客户端。http.HandleFunc
函数中完成的,就是在这个例子中当根路径“/”(url地址是http://localhost:8080 )被请求的时候(或者这个服务器上的其他地址),HelloServer
函数就被执行了。这个函数是http.HandlerFunc
类型的,它们通常用使用Prehandler来命名,在前边加了一个Pref前缀。http.HandleFunc
注册了一个处理函数(这里是HelloServer
)来处理对应/
的请求。/
可以被替换为其他特定的url比如/create
,/edit
等等;你可以为每一个特定的url定义一个单独的处理函数。这个函数需要两个参数:第一个是ReponseWriter
类型的w
;第二个是请求req
。程序向w
写入了Hello
和r.URL.Path[1:]
组成的字符串后边的[1:]
表示“创建一个从第一个字符到结尾的子切片”,用来丢弃掉路径开头的“/”,fmt.Fprintf()
函数完成了本次写入(请看章节12.8);另外一种写法是io.WriteString(w, "hello, world!\n")
http://localhost:8080/world
,浏览器就会出现文字:Hello, world
,网页服务器会响应你在:8080/
后边输入的内容fmt.Println
在控制台打印状态,在每个handler被请求的时候,在他们内部打印日志会很有帮助fmt.Fprint
和fmt.Fprintf
都是用来写入http.ResponseWriter
的不错的函数(他们实现了io.Writer
)。 比如我们可以使用title
和body
的值http.ListenAndServeTLS()
代替http.ListenAndServe()
4)http.HandleFunc("/", Hfunc)
中的HFunc
是一个处理函数,如下:http.Handle("/", http.HandlerFunc(HFunc))
HandlerFunc
只是一个类型名称,它定义如下:f
函数声明的合适,HandlerFunc(f)
就是一个执行了f
函数的处理器对象。http.Handle
的第二个参数也可以是T
的一个obj对象:http.Handle("/", obj)
给T提供了ServeHTTP
方法,实现了http的Handler
接口:http://localhost:9999/hello/Name
时,响应:hello Name
(Name需是一个合法的姓,比如Chris或者Madeleine)http://localhost:9999/shouthello/Name
时,响应:hello NAME
hello
并使它实现http.Handler
。运行并测试。