/
router.go
144 lines (117 loc) · 3.82 KB
/
router.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package rest
import (
"fmt"
"github.com/json-iterator/go"
"io"
"net/http"
"os"
"strings"
)
//用于处理所有前来的请求
type Router struct {
context *Context
routeMap map[string]func(writer http.ResponseWriter, request *http.Request)
}
//构造方法
func NewRouter(context *Context) *Router {
router := &Router{
context: context,
routeMap: make(map[string]func(writer http.ResponseWriter, request *http.Request)),
}
for _, controller := range context.ControllerMap {
routes := controller.RegisterRoutes()
for k, v := range routes {
router.routeMap[k] = v
}
}
return router
}
//全局的异常捕获
func (this *Router) GlobalPanicHandler(writer http.ResponseWriter, request *http.Request) {
if err := recover(); err != nil {
LogError(fmt.Sprintf("全局异常: %v", err))
var webResult *WebResult = nil
if value, ok := err.(string); ok {
writer.WriteHeader(http.StatusBadRequest)
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: value}
} else if value, ok := err.(int); ok {
writer.WriteHeader(http.StatusBadRequest)
webResult = ConstWebResult(value)
} else if value, ok := err.(*WebResult); ok {
writer.WriteHeader(http.StatusBadRequest)
webResult = value
} else if value, ok := err.(WebResult); ok {
writer.WriteHeader(http.StatusBadRequest)
webResult = &value
} else if value, ok := err.(*WebError); ok {
writer.WriteHeader(value.Code)
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: value.Msg}
} else if value, ok := err.(WebError); ok {
writer.WriteHeader((&value).Code)
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: (&value).Msg}
} else if value, ok := err.(error); ok {
writer.WriteHeader(http.StatusBadRequest)
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: value.Error()}
} else {
writer.WriteHeader(http.StatusInternalServerError)
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: "服务器未知错误"}
}
//输出的是json格式 返回的内容申明是json,utf-8
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
//用json的方式输出返回值。
var json = jsoniter.ConfigCompatibleWithStandardLibrary
b, _ := json.Marshal(webResult)
fmt.Fprintf(writer, string(b))
}
}
//让Router具有处理请求的功能。
func (this *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
//每个请求的入口在这里
//全局异常处理。
defer this.GlobalPanicHandler(writer, request)
path := request.URL.Path
if strings.HasPrefix(path, "/api") {
if handler, ok := this.routeMap[path]; ok {
handler(writer, request)
} else {
//直接将请求扔给每个controller,看看他们能不能处理,如果都不能处理,那就算了。
canHandle := false
for _, controller := range this.context.ControllerMap {
if handler, exist := controller.HandleRoutes(writer, request); exist {
canHandle = true
handler(writer, request)
break
}
}
if !canHandle {
panic(fmt.Sprintf("没有找到能够处理%s的方法\n", path))
}
}
} else {
//当作静态资源处理。默认从当前文件下面的static文件夹中取东西。
dir := GetHtmlPath()
requestURI := request.RequestURI
if requestURI == "" || request.RequestURI == "/" {
requestURI = "index.html"
}
filePath := dir + requestURI
exists, _ := PathExists(filePath)
if !exists {
filePath = dir + "/index.html"
exists, _ = PathExists(filePath)
if !exists {
panic(fmt.Sprintf("404 not found:%s", filePath))
}
}
writer.Header().Set("Content-Type", GetMimeType(GetExtension(filePath)))
diskFile, err := os.Open(filePath)
if err != nil {
panic("cannot get file.")
}
defer diskFile.Close()
_, err = io.Copy(writer, diskFile)
if err != nil {
panic("cannot get file.")
}
}
}