Go语言学习14-常见任务 内置的 JSON 解析 利用反射实现, 通过 FieldTag 来标识对应的 json 值
1 2 3 4 5 6 7 8 9 10 11 type BasicInfo struct { Name string `json:"name"` Age int `json:"age"` } type JobInfo struct { Skills []string `json:"skills"` } type Employee struct { BasicInfo BasicInfo `json:"basic_info"` JobInfo JobInfo `json:"job_info"` }
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 var jsonStr = `{ "basic_info":{ "name":"Mike", "age":30 }, "job_info":{ "skills": ["Java", "Go", "C"] } }` func TestEmbeddedJson (t *testing.T) { e := new (Employee) err := json.Unmarshal([]byte (jsonStr), e) if err != nil { t.Error(err) } fmt.Println(*e) if v, err := json.Marshal(e); err == nil { fmt.Println(string (v)) } else { t.Error(err) } }
更快的 JSON 解析 EasyJSON 采用代码生成而非反射
安装
1 go get -u github.com/mailru/easyjson/...
使用
HTTP Server 1 2 3 4 5 6 7 8 9 10 11 12 func main () { http.HandleFunc("/" , func (w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World!" ) }) http.HandleFunc("/time/" , func (w http.ResponseWriter, r *http.Request) { t := time.Now() timeStr := fmt.Sprintf("{\"time\": \"%s\"}" , t) w.Write([]byte (timeStr)) }) http.ListenAndServe(":8080" , nil ) }
路由规则
URL 分为两种,末尾是 / :表示一个子树,后面可以跟其他子路径; 末尾不 是 /,表示一个叶子,固定的路径
以/ 结尾的 URL 可以匹配它的任何子路径,比如 /images 会匹配 /images/cute-cat.jpg
它采用最长匹配原则,如果有多个匹配,一定采用匹配路径最长的那个进行处
理
如果没有找到任何匹配项,会返回 404 错误
Default Router 1 2 3 4 5 6 7 8 9 10 func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) { handler := sh.srv.Handler if handler == nil { handler = DefaultServeMux } if req.RequestURI == "*" && req.Method == "OPTIONS" { handler = globalOptionsHandler{} } handler.ServeHTTP(rw, req) }
构建Restful服务 更好的Router https://github.com/julienschmidt/httprouter
1 2 3 4 5 6 7 8 9 10 11 func Hello (w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w, "hello, %s!\n" , ps.ByName("name" )) } func main () { router := httprouter.New() router.GET("/" , Index) router.GET("/hello/:name" , Hello) log.Fatal(http.ListenAndServe(":8080" , router)) }
面向资源的架构(Resource Oriented Architecture)
In software engineering, a resource -oriented architecture (ROA) is a style of software architecture and programming paradigm for supportive designing and developing software in the form of Internetworking of resources with “RESTful” interfaces.
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 type Employee struct { ID string `json:"id"` Name string `json:"name"` Age int `json:"age"` } var employeeDB map [string ]*Employeefunc init () { employeeDB = map [string ]*Employee{} employeeDB["Mike" ] = &Employee{ ID: "e-1" , Name: "Mike" , Age: 35 , } employeeDB["Rose" ] = &Employee{ ID: "e-2" , Name: "Rose" , Age: 45 , } } func Index (w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, "Welcome!\n" ) } func GetEmployeeByName (w http.ResponseWriter, r *http.Request, ps httprouter.Params) { qName := ps.ByName("name" ) var ( ok bool info *Employee infoJson []byte err error ) if info, ok = employeeDB[qName]; !ok { w.Write([]byte ("{\"error\":\"Not Found\"}" )) return } if infoJson, err = json.Marshal(info); err != nil { w.Write([]byte (fmt.Sprintf("{\"error\":,\"%s\"}" , err))) return } w.Write(infoJson) } func main () { router := httprouter.New() router.GET("/" , Index) router.GET("/employees/:name" , GetEmployeeByName) log.Fatal(http.ListenAndServe("localhost:8080" , router)) }