tank/rest/router.go
2018-01-17 01:16:34 +08:00

138 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 {
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: value}
} else if value, ok := err.(int); ok {
webResult = ConstWebResult(value)
} else if value, ok := err.(*WebResult); ok {
webResult = value
} else if value, ok := err.(WebResult); ok {
webResult = &value
} else if value, ok := err.(error); ok {
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: value.Error()}
} else {
webResult = &WebResult{Code: RESULT_CODE_UTIL_EXCEPTION, Msg: "服务器未知错误"}
}
//输出的是json格式 返回的内容申明是jsonutf-8
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
//用json的方式输出返回值。
var json = jsoniter.ConfigCompatibleWithStandardLibrary
b, _ := json.Marshal(webResult)
if webResult.Code == RESULT_CODE_OK {
writer.WriteHeader(http.StatusOK)
} else {
writer.WriteHeader(http.StatusBadRequest)
}
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", requestURI))
}
}
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.")
}
}
}