我们都知道,go语言的编程方式是duck type,也就是,接口和实现类是完全解耦的,如果一个接口实现了某个接口的方法,则实现了这个接口。这给编程和灵活性带来了极大的可变性和灵活性。
Go中的ServerHTTP在go语言中如果要开启一个Web服务,则要实现http.Handler提供的ServerHTTP方法
这是Handler接口的源码:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
开启一个简单的Http服务:
main(){
server := http.Server{
Addr:"localhost:8080",
}
server.ListenAndServer()
}
通过实现Handler接口来开启Http服务
package main
import (
"fmt"
"net/http"
)
type HelloHandler struct {
}
func (HelloHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprintf(w, "hello")
}
type WorldHandler struct {
}
func (WorldHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprintf(w, "world")
}
func main() {
server := http.Server{
Addr: "localhost:8080",
}
http.Handle("/hello", HelloHandler{})
http.Handle("/world", WorldHandler{})
server.ListenAndServe()
}
如上所示,如果需要n个不同的处理器,则需要新建n个结构体,然后实现Handler接口的方法,那我们可以用更加简便的方式:
通过HandlerFunc开启多个服务http.HandlerFunc的方法签名
type HandlerFunc func(ResponseWriter, *Request)
它对实现ServerHTTP的防范形式参数进行封装,编程了一个类型,但是他还是一个匿名的ServerHTTP方法。
它也实现了ServerHTTP方法:然后再调用它所调用的方法
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter,r *http.Request) {
_, _ = fmt.Fprintf(w, "hello")
}
func world(w http.ResponseWriter,r *http.Request) {
_, _ = fmt.Fprintf(w, "world")
}
func main() {
server := http.Server{
Addr: "localhost:8080",
}
http.HandleFunc("/hello", hello)
http.HandleFunc("/hello", world)
server.ListenAndServe()
}
这样不用新建好多结构体,直接使用方法来实现,简便了很多
嵌套实现多切面:在java中AOP思想很出名,因为其可以简便很多代码,其实在go中,也可实现其功能:
使用HandlerFunc来实现串联web服务
package main
import (
"fmt"
"net/http"
"reflect"
"runtime"
)
func hello( w http.ResponseWriter,r *http.Request) {
_, _ = fmt.Fprint(w, "Hello")
fmt.Println("hello")
}
func log(h http.HandlerFunc) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
name := runtime.FuncForPC(reflect.ValueOf(h).Pointer()).Name()
fmt.Println("handler func called name:", name)
h(writer, request)
}
}
func main() {
server := http.Server{
Addr: "localhost:8080",
}
http.HandleFunc("/hello",log(hello))
server.ListenAndServe()
}
使用Handler来实现串联web服务
package main
import (
"fmt"
"net/http"
)
type HelloStruct struct {
}
func (HelloStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello")
}
func log1(h http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
fmt.Println("handler func called name:", "hkfhsf")
h.ServeHTTP(writer, request)
})
}
func protect(h http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
fmt.Println("protect")
h.ServeHTTP(writer, request)
})
}
func main() {
server := http.Server{
Addr: "localhost:8080",
}
helloStruct := HelloStruct{}
http.Handle("/meme", protect(log1(helloStruct)))
server.ListenAndServe()
}