1 Star 0 Fork 0

rainman/goboot

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
webroute.go 9.85 KB
一键复制 编辑 原始数据 按行查看 历史
rainman 提交于 2026-01-14 17:17 +08:00 . 新增sche支持
package goboot
import (
"fmt"
"net/http"
"reflect"
"runtime/debug"
"strconv"
"strings"
"time"
)
// webRoute 路由处理
// 1. 初始化WebDocMethods
// 2. 绑定URL方法
// 3. 静态文件目录
// 4. 动态自动路由
func webRoute(staticFileDir *string) {
initWebDocMethods(false)
bindUrlMethod()
//静态文件目录
if staticFileDir != nil {
fs := http.FileServer(http.Dir(*staticFileDir))
http.Handle("/", http.StripPrefix("/", fs))
}
//动态自动路由
for urlPath, webDocMethodMap := range webDocMethodUrlMap {
finalUrlPath := urlPath
needMatch := false
for _, webMathod := range webDocMethodMap {
fmt.Println("MappingUrl : " + webMathod.UrlPath + " " + webMathod.WebMethod + " " + strings.Join(webMathod.PathParams, ","))
if len(webMathod.PathParams) > 0 {
needMatch = true
break
}
}
if needMatch {
finalUrlPath += "/"
}
//fmt.Println("MappingUrl : " + finalUrlPath)
http.HandleFunc(finalUrlPath, func(w http.ResponseWriter, r *http.Request) {
//处理panic
defer func() {
if err := recover(); err != nil {
//打印错误堆栈
fmt.Printf("err=%v, stack=%s\n", err, string(debug.Stack()))
serverConfig.HandleReturn(w, nil, fmt.Errorf("%v", err))
}
}()
sTime := time.Now().UnixMilli()
w.Header().Set("content-type", "application/json")
fmt.Println("DoingUrl : " + r.Method + " " + r.URL.Path)
//获取WebDocMethod
webDocMethod, ok := webDocMethodMap[r.Method]
if !ok {
webDocMethod, ok = webDocMethodMap[""]
if !ok {
if r.Method != http.MethodOptions {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
}
}
paramMap := map[string][]any{}
//路径参数判断
if strings.HasSuffix(finalUrlPath, "/") { //带路径参数
pa := strings.Replace(r.URL.Path, finalUrlPath[:len(finalUrlPath)-2], "", 1)
pathParams := strings.Split(pa, "/")
if len(pathParams) != len(webDocMethod.PathParams)+1 {
w.WriteHeader(http.StatusNotFound)
return
}
//处理路径参数
for i, pathParam := range webDocMethod.PathParams {
paramMap[pathParam] = append(paramMap[pathParam], pathParams[i+1])
}
}
if r.Method == http.MethodPost {
r.ParseMultipartForm(10 << 20) // 10MB
//处理POST参数
for sss, urlParamValue := range r.PostForm {
for _, v := range urlParamValue {
paramMap[sss] = append(paramMap[sss], v)
}
}
}
if len(paramMap) == 0 {
//处理参数
r.ParseForm()
//处理GET参数
for sss, urlParamValue := range r.Form {
for _, v := range urlParamValue {
paramMap[sss] = append(paramMap[sss], v)
}
}
}
//fmt.Println(paramMap)
selfResponseWriter := false
var curWebUrlAspect []WebUrlAspect
for _, aspect := range WebUrlAspectList {
if aspect.MathchAspect(webDocMethod) {
curWebUrlAspect = append(curWebUrlAspect, aspect)
}
}
for _, aspect := range curWebUrlAspect {
err := aspect.DoAspect(r, &paramMap)
if err != nil {
serverConfig.HandleReturn(w, nil, err)
return
}
}
//调用方法
callParams := make([]reflect.Value, len(webDocMethod.ParamList))
for i, param := range webDocMethod.ParamList {
//处理默认值
if param.DefStr != "" && len(paramMap[param.Name]) == 0 {
paramMap[param.Name] = append(paramMap[param.Name], param.DefStr)
}
if param.TypeName == "string" {
//必须有值
if len(paramMap[param.Name]) == 0 {
serverConfig.HandleReturn(w, nil, fmt.Errorf(param.Name+"参数必须有值"))
return
}
var paramStr string
if len(paramMap[param.Name]) > 0 {
paramStr = paramMap[param.Name][0].(string)
}
callParams[i] = reflect.ValueOf(paramStr)
} else if param.TypeName == "*string" {
var paramStr *string
if len(paramMap[param.Name]) > 0 {
midStr := paramMap[param.Name][0].(string)
paramStr = &midStr
}
callParams[i] = reflect.ValueOf(paramStr)
} else if param.TypeName == "float64" {
//必须有值
if len(paramMap[param.Name]) == 0 {
serverConfig.HandleReturn(w, nil, fmt.Errorf(param.Name+"参数必须有值"))
return
}
var paramFloat64 float64
var err error
if len(paramMap[param.Name]) > 0 {
paramFloat64, err = strconv.ParseFloat(paramMap[param.Name][0].(string), 64)
if err != nil {
panic(err)
}
}
callParams[i] = reflect.ValueOf(paramFloat64)
} else if param.TypeName == "*float64" {
if len(paramMap[param.Name]) > 0 { //有值
paramFloat64, err := strconv.ParseFloat(paramMap[param.Name][0].(string), 64)
if err != nil {
panic(err)
}
callParams[i] = reflect.ValueOf(&paramFloat64)
} else {
var paramFloat64 *float64
callParams[i] = reflect.ValueOf(paramFloat64)
}
} else if param.TypeName == "*float32" {
if len(paramMap[param.Name]) > 0 { //有值
paramFloat32, err := strconv.ParseFloat(paramMap[param.Name][0].(string), 32)
if err != nil {
panic(err)
}
callParams[i] = reflect.ValueOf(&paramFloat32)
} else {
var paramFloat32 *float32
callParams[i] = reflect.ValueOf(paramFloat32)
}
} else if param.TypeName == "int64" {
//必须有值
if len(paramMap[param.Name]) == 0 {
serverConfig.HandleReturn(w, nil, fmt.Errorf(param.Name+"参数必须有值"))
return
}
var paramInt64 int64
var err error
if len(paramMap[param.Name]) > 0 {
paramInt64, err = strconv.ParseInt(paramMap[param.Name][0].(string), 10, 64)
if err != nil {
panic(err)
}
}
callParams[i] = reflect.ValueOf(paramInt64)
} else if param.TypeName == "*int64" {
if len(paramMap[param.Name]) > 0 { //有值
paramInt64, err := strconv.ParseInt(paramMap[param.Name][0].(string), 10, 64)
if err != nil {
panic(err)
}
callParams[i] = reflect.ValueOf(&paramInt64)
} else {
var paramInt64 *int64
callParams[i] = reflect.ValueOf(paramInt64)
}
} else if param.TypeName == "int32" {
//必须有值
if len(paramMap[param.Name]) == 0 {
serverConfig.HandleReturn(w, nil, fmt.Errorf(param.Name+"参数必须有值"))
return
}
var paramInt32 int32
if len(paramMap[param.Name]) > 0 {
paramInt64, err := strconv.ParseInt(paramMap[param.Name][0].(string), 10, 32)
if err != nil {
panic(err)
}
paramInt32 = int32(paramInt64)
}
callParams[i] = reflect.ValueOf(paramInt32)
} else if param.TypeName == "*int32" {
if len(paramMap[param.Name]) > 0 { //有值
var paramInt32 int32
paramInt364, err := strconv.ParseInt(paramMap[param.Name][0].(string), 10, 32)
if err != nil {
panic(err)
}
paramInt32 = int32(paramInt364)
callParams[i] = reflect.ValueOf(&paramInt32)
} else {
var paramInt32 *int32
callParams[i] = reflect.ValueOf(paramInt32)
}
} else if param.TypeName == "int" {
//必须有值
if len(paramMap[param.Name]) == 0 {
serverConfig.HandleReturn(w, nil, fmt.Errorf(param.Name+"参数必须有值"))
return
}
var paramInt int
var err error
if len(paramMap[param.Name]) > 0 {
paramInt, err = strconv.Atoi(paramMap[param.Name][0].(string))
if err != nil {
panic(err)
}
}
callParams[i] = reflect.ValueOf(paramInt)
} else if param.TypeName == "*int" {
if len(paramMap[param.Name]) > 0 { //有值
paramInt, err := strconv.Atoi(paramMap[param.Name][0].(string))
if err != nil {
panic(err)
}
callParams[i] = reflect.ValueOf(&paramInt)
} else {
var paramInt *int
callParams[i] = reflect.ValueOf(paramInt)
}
} else if param.TypeName == "bool" {
//必须有值
if len(paramMap[param.Name]) == 0 {
serverConfig.HandleReturn(w, nil, fmt.Errorf(param.Name+"参数必须有值"))
return
}
var paramBool bool
var err error
if len(paramMap[param.Name]) > 0 {
paramBool, err = strconv.ParseBool(paramMap[param.Name][0].(string))
if err != nil {
panic(err)
}
}
callParams[i] = reflect.ValueOf(paramBool)
} else if param.TypeName == "*bool" {
if len(paramMap[param.Name]) > 0 { //有值
paramBool, err := strconv.ParseBool(paramMap[param.Name][0].(string))
if err != nil {
panic(err)
}
callParams[i] = reflect.ValueOf(&paramBool)
} else {
var paramBool *bool
callParams[i] = reflect.ValueOf(paramBool)
}
} else if param.TypeName == "http.Request" {
panic("Request参数不能是值类型")
} else if param.TypeName == "*http.Request" {
callParams[i] = reflect.ValueOf(r)
} else if param.TypeName == "http.ResponseWriter" {
callParams[i] = reflect.ValueOf(w)
selfResponseWriter = true
} else {
if len(paramMap[param.Name]) == 0 {
callParams[i] = reflect.ValueOf(nil)
} else {
callParams[i] = reflect.ValueOf(paramMap[param.Name][0])
}
}
}
callReturn := webDocMethod.methodValue.Call(callParams)
if callReturn[1].Interface() != nil { //错误
for i := len(curWebUrlAspect) - 1; i >= 0; i-- {
curWebUrlAspect[i].DoAspectAfter(callReturn[0].Interface(), callReturn[1].Interface().(error))
}
} else {
for i := len(curWebUrlAspect) - 1; i >= 0; i-- {
curWebUrlAspect[i].DoAspectAfter(callReturn[0].Interface(), nil)
}
}
tTime := time.Now().UnixMilli()
fmt.Printf(" %dms %s\n", tTime-sTime, r.URL.Path)
if selfResponseWriter {
return
}
if callReturn[1].Interface() != nil { //错误
serverConfig.HandleReturn(w, callReturn[0].Interface(), callReturn[1].Interface().(error))
} else {
serverConfig.HandleReturn(w, callReturn[0].Interface(), nil)
}
})
}
fmt.Println("WebRoute Init Ok")
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/rainsuperman/goboot.git
git@gitee.com:rainsuperman/goboot.git
rainsuperman
goboot
goboot
v1.0.5

搜索帮助