go 网络编程

  • 客户端网络访问
package main

import (
  "fmt"
  "io/ioutil"
  "net/http"
)

func main() {
  testHttpNewRequest()
}

func testHttpNewRequest()  {
  // 1.创建一个客户端
  client := http.Client{}
  // 2.创建一个请求,请求方式既可以是GET, 也可以是POST
  request, err := http.NewRequest("GET", "https://www.toutiao.com/search/suggest/initial_page/", nil)

  checkErr(err)
  // 3.客户端发送请求
  cookName := &http.Cookie{Name:"username", Value: "Steven"}
  // 添加cookie
  request.AddCookie(cookName)

  // 设置请求头
  request.Header.Set("Accept-Language", "zh-cn")
  fmt.Printf("Header:%v \n", request.Header)

  response, err := client.Do(request)
  checkErr(err)
  defer response.Body.Close()
  // 查看请求头的数据
  fmt.Printf("相应状态码:%v \n", response.StatusCode)
  // 4.操作数据
  if response.StatusCode == 200 {
   data, err := ioutil.ReadAll(response.Body)
   fmt.Println("网络请求成功")
   checkErr(err)
   fmt.Println(string(data))
  } else {
   fmt.Println("网络请求失败", response.Status)
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}



  • 使用client. Get()方法
package main

import (
  "fmt"
  "net/http"
)

func main() {
  testClientGet()
}

func testClientGet()  {
  // 创建客户端
  client := http.Client{}
  // 通过client去请求
  response, err := client.Get("https://www.toutiao.com/search/suggest/initial_page/")
  checkErr(err)
  fmt.Printf("响应状态码:%v \n", response.StatusCode)
  if response.StatusCode == 200 {
    fmt.Println("网络请求成功")
    defer response.Body.Close()
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}

  • 使用client. Post()或client.PostForm()方法
  • 使用http. Get()方法
package main

import (
  "fmt"
  "net/http"
)

func main() {
  testHttpGet()
}

func testHttpGet()  {

  response, err := http.Get("http://www.baidu.com")
  checkErr(err)
  fmt.Printf("响应状态码:%v \n", response.StatusCode)
  if response.StatusCode == 200 {
    fmt.Println("网络请求成功")
    defer response.Body.Close()
  } else {
    fmt.Println("请求失败",response.Status)
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}

  • 使用http. Post()或http.PostForm()方法
package main

import (
  "fmt"
  "net/http"
  "net/url"
  "strings"
)

func main() {
  testHttpPost()
}

func testHttpPost()  {
  //构建参数
  data := url.Values{
    "theCityName" : {"重庆"},
  }
  // 参数转化为body
  reader := strings.NewReader(data.Encode())
  fmt.Println(reader)
  // 发起post请求,MIME 格式
  response, err := http.Post("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getWeatherbyCityName",
    "application/x-www-form-urlencoded",reader)

  checkErr(err)
  fmt.Printf("响应状态码:%v \n", response.StatusCode)
  if response.StatusCode == 200 {
    fmt.Println("网络请求成功")
    defer response.Body.Close()
  } else {
    fmt.Println("请求失败",response.Status)
  }
}

func checkErr(err error)  {
  fmt.Println("09-----------")
  defer func() {
    if ins,ok := recover().(error);ok { // 这种recover的使用方式
      fmt.Println("程序出现异常:", ins.Error())
    }
  }()
  if err != nil {
    panic(err)
  }

}

  • webserver 使用http. FileServer ()方法
package main

import "net/http"

func main() {
  testFileServer()
}
func testFileServer()  {
  // 如果该路径里有index.html 文件,会优先显示html文件,否则会看到文件目录
  http.ListenAndServe(":2003",http.FileServer(http.Dir("./files/")))
}


  • 使用http. HandleFunc()方法
package main

import (
  "fmt"
  "net/http"
)

func main() {
  // 绑定路径,去触发方法
  http.HandleFunc("/index",indexHandler)
  // 绑定端口
  // 第一个参数为监听地址,第二个参数标识服务器处理程序,通常为nil, 这意味着服务端调用http.DefaultServeMux 进行处理
  err := http.ListenAndServe(":3013",nil)
  fmt.Println(err)
}

func indexHandler(w http.ResponseWriter, r *http.Request)  {
  fmt.Println("/index=======")
  w.Write([]byte("这是默认首页"))
}


  • 使用http.NewServeMux()方法
  • 服务端获取客户端请求数据
  • golang模板
  • map转JSON
package main

import (
  "encoding/json"
  "fmt"
)

func main() {
  // 定义一个map变量并初始化
  m := map[string][]string{
    "level":{"debug"},
    "message":{"file not found","stack overflow"},
  }
  fmt.Println(m)
  // 将map解析成json格式
  if data,err := json.Marshal(m);err==nil {
    fmt.Printf("%s \n", data)
  }
}
  • map 转json 缩进
package main

import (
  "encoding/json"
  "fmt"
)

func main() {
  // 定义一个map变量并初始化
  m := map[string][]string{
    "level":{"debug"},
    "message":{"file not found","stack overflow"},
  }
  fmt.Println(m)
  // 将map解析成json格式
  if data,err := json.MarshalIndent(m,""," ");err==nil {
    fmt.Printf("%s \n", data)
  }
}


  • 结构体转JSON
package main

import (
  "encoding/json"
  "fmt"
)

type DebugInfo struct {
  Level string
  Msg string
  author string // 未导出字段不会被json解析(首字母小写)
}
func main() {
  // 定义一个结构体切片并初始化
  debugInfos := []DebugInfo{
    DebugInfo{"debug", `file:"test.txt" not found`, "cynhard"} ,
    DebugInfo{"", "logic error", "Gopher"} ,
  }
  // 将结构体解析成JSON格式
  if data,err := json.Marshal(debugInfos);err == nil {
    fmt.Printf("%s \n", data)
  }
}

  • 结构体字段标签
package main

import (
  "encoding/json"
  "fmt"
)

// 可通过结构体标签,改变编码后json字符串的键名
type User struct {
  Name string `json:"_name"`
  Age int `json:"_age"`
  Sex uint `json:"-"` // 不解析
  Address string // 不改变key标签
}

var user = User {
  Name:"Steven",
  Age:35,
  Sex:1,
  Address: "北京海淀区",
}
func main() {
  arr, _ := json.Marshal(user)
  fmt.Println(string(arr))
}

  • json包在解析匿名字段
package main

import (
  "encoding/json"
  "fmt"
)

type Point struct {
  X,Y int
}
type Circle struct {
  Point
  Radius int
}
func main() {
  // 解析匿名字段
  if data, err := json.Marshal(Circle{Point{50,50},25});err == nil {
    fmt.Printf("%s \n", data)
  }
}

  • json 转切片
package main

import (
  "encoding/json"
  "fmt"
)

func main() {
  // 定义json格式的字符串
  data := `[{"Level":"debug","msg1":"file:\"test.txt\" not found"}, {"Level":"","msg2":"logic error"}]`
  var debugInfos []map[string]string
  // 将字符串解析成map切片
  json.Unmarshal([]byte(data), &debugInfos)
  fmt.Println(debugInfos)
}
  • json 转结构体
package main

import (
  "encoding/json"
  "fmt"
)

type DebugInfo struct {
  Level string
  Msg string
  author string // 未导出字段不会被json解析
}

func (debugInfo DebugInfo) String() string {
  return fmt.Sprintf("{Level:%s, Msg:%s}",debugInfo.Level,debugInfo.Msg)
}
func main() {
  // 定义json格式的字符串
  data := `[{"Level":"debug","Msg":"file:\"test.txt\" not found","author":"abc"}, {"Level":"","Msg":"logic error","author":"ddd"}]`
  var debugInfos []DebugInfo
  // 将字符串解析成结构体切片
  json.Unmarshal([]byte(data), &debugInfos)
  fmt.Println(debugInfos)
}

  • 解码时依然支持结构体字段标签,规则和编码时一样
package main

import (
  "encoding/json"
  "fmt"
)

type DebugInfo struct {
  Level string `json:"level"` // level 解码成 Level
  Msg string  `json:"message"` // message 解码成 Msg
  Author string `json:"-"` // 忽略Author
}

func (debugInfo DebugInfo) String() string {
 return fmt.Sprintf("{Level:%s, Msg:%s}",debugInfo.Level,debugInfo.Msg)
}
func main() {
  // 定义json格式的字符串
  data := `[{"level":"debug","message":"file:\"test.txt\" not found","author":"abc"}, {"level":"","message":"logic error","author":"ddd"}]`
  var debugInfos []DebugInfo
  // 将字符串解析成结构体切片
  json.Unmarshal([]byte(data), &debugInfos)
  fmt.Println(debugInfos)
}
  • 匿名字段解析
package main

import (
  "encoding/json"
  "fmt"
)

type Point struct {
  X,Y int
}
type Circle struct {
  Point
  Radius int
}

func main() {
  // 定义json格式字符串
  data := `{"X":80,"Y":80,"Radius":60}`
  var c Circle
  json.Unmarshal([]byte(data), &c)
  fmt.Println(c)
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351