学习了一下go语言的基本语法,实现了一个简单的http服务,监听两个路径 http://your_host:your_port/get 和 http://your_host:your_port/post ,接收请求后做校验,并将数据返回给请求端,都以json通讯。
示例代码如下(已经测试通过):
package main // 包名称,一个目录下,只能有一个名称为main的package
import ( // 需要引入的包,包的顺序无所谓,但是如果环境里没有,就会报错
"fmt"
"log"
"net/http"
"encoding/json"
"io/ioutil"
)
type myresp struct { // 定义结构体
Id int `json:"id"` // 反引号里的内容是要在json编码时,导出到json里的内容,字段的首字母必须要大写
Name string `json:"name"`
Behave []string `json:"behave"`
}
type Intelinfo struct {
Code int `json:"code"`
Msg string `json:"msg"`
}
func index(w http.ResponseWriter, r *http.Request) {
_resp := myresp { // 定义一个返回的结构体,注意实例时,需要有冒号和逗号,而定义时没有的
Id: 123,
Name: "test_name",
Behave: []string{"behave1", "behave2", "behave3"}, // 注意数组的初始化方式
}
// fmt.Println(_resp) // 注释是不会执行的
bjson, jerr := json.Marshal(_resp) // 需要注意 := 仅仅用于在函数内部初始化之前没有定义或声明过的变量,并且如果下文未使用,会报错
// fmt.Println(bjson)
if jerr != nil { // if 语句没有括号,这个需要注意
fmt.Println("json.Marshal_err:", jerr)
}
w.Header().Set("Content-Type", "application/json") // 设置响应的包头
fmt.Fprintf(w, string(bjson))
}
func handle_service_info(w http.ResponseWriter, r *http.Request) {
var bjson string // 声明一个函数中的全局变量
/*
* 注意map的用法 map[your_type]your_type_with_no_space_after_bracket
* 但是这样初始化有问题,因为值可能是值类型,而不是string
*/
var user map[string]string
body, _ := ioutil.ReadAll(r.Body)
unmar_err := json.Unmarshal(body, &user)
if unmar_err != nil {
bjson = "decode json error"
} else {
if (user["username"] == "test" && user["password"] == "test") { // if 也可以加上括号
_resp := Intelinfo {
Code: 0,
Msg: "ok",
}
mjson, jerr := json.Marshal(_resp) // 这里mjson只是为了暂存一下decode的结果
// fmt.Println(bjson)
if jerr != nil {
fmt.Println("json.Marshal_err:", jerr)
}
w.Header().Set("Content-Type", "application/json")
bjson = string(mjson) // decode的结果在给到之前声明过的变量
} else {
bjson = "username & password error"
}
}
fmt.Fprintf(w, string(bjson)) // func origin format: func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
}
func main() {
http.HandleFunc("/get", index) // 配置监听的路由
http.HandleFunc("/post", handle_service_info) // 配置监听的路由
err := http.ListenAndServe(":9191", nil) // 监听的端口
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
执行方式: go run the_name_you_save_the_upper_code_for.go