http程式設計
1) Go原生支援 http : import ("net/http")
2) Go 的 http 服務性能和 nginx 比較接近
3) 幾行代碼就可以實作一個 web 服務
http 服務端
// 示例代碼:
package main
import (
"fmt"
"net/http"
)
func Hello(w http.ResponseWriter, r *http.Request){
fmt.Println("hello world\n")
fmt.Fprintf(w,"hello world") // 傳回響應
}
func main(){
http.HandleFunc("/",Hello) // 路由;第一個參數是路徑,第二個參數是視圖函數
err := http.ListenAndServe("0.0.0.0:8080",nil) // 監聽并等待請求
if err != nil{
fmt.Println("http listened failed")
}
}
http 用戶端
// 示例代碼:
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main(){
ret,err := http.Get("https://www.baidu.com/") // 向一個伺服器發送 GET 請求;傳回的資料都在 ret.Body 裡面
if err != nil {
fmt.Println("get err:",err)
return
}
data,err := ioutil.ReadAll(ret.Body) // 傳回的資料都在 ret.Body 裡面
if err != nil {
fmt.Println("get data err:",err)
return
}
fmt.Printf("Type:%T\n",data)
fmt.Println(string(data))
}
// 運作結果:
[[email protected] example01_http_client]# go run main/main.go
Type:[]uint8
<html>
<head>
<script>
location.replace(location.href.replace("https://","http://"));
</script>
</head>
<body>
<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
[[email protected] example01_http_client]#
http常見請求方法
1)Get請求
2)Post請求
3)Put請求
4)Delete請求
5)Head請求 -- > 隻請求頁面的頭部
發送 HEAD 請求
// 示例代碼:
package main
import (
"fmt"
"net/http"
)
var urls = []string{
"http://www.baidu.com",
"http://www.google.com",
"http://www.taobao.com",
}
func main(){
for _,v := range urls{
resp,err := http.Head(v) // 發送 Head 請求
if err != nil {
fmt.Printf("head %s failed,err:%v\n",v,err)
continue
}
fmt.Printf("head success,status:%v\n",resp.Status) // resp.Status --> 狀态碼
}
}
// 運作結果:
[[email protected] example01_http_head_request]# go run main/main.go
head success,status:200 OK
head http://www.google.com failed,err:Head http://www.google.com: dial tcp 75.126.2.43:80: connect: connection timed out
head success,status:200 OK
[[email protected] example01_http_head_request]#
// 自定義逾時時間
// 示例代碼:
package main
import (
"fmt"
"net/http"
"time"
"net"
)
var urls = []string{
"http://www.baidu.com",
"http://www.google.com",
"http://www.taobao.com",
}
func main(){
for _,v := range urls{
c := http.Client{ // 自定義用戶端
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error){
timeout := time.Second * 2 // 自定義逾時時間
return net.DialTimeout(network, addr, timeout)
},
},
}
start := time.Now()
resp,err := c.Head(v) // 用自定義的用戶端發送請求
end := time.Now()
interval := end.Sub(start)
fmt.Println("interval:",interval)
//resp,err := http.Head(v) // 發送 Head 請求
if err != nil {
fmt.Printf("head %s failed,err:%v\n",v,err)
continue
}
fmt.Printf("head success,status:%v\n",resp.Status) // resp.Status --> 狀态碼
}
}
// 運作結果:
[[email protected] example01_http_head_request]# go run main/main.go
interval: 171.062376ms
head success,status:200 OK
interval: 2.000789206s
head http://www.google.com failed,err:Head http://www.google.com: dial tcp 69.63.184.142:80: i/o timeout
interval: 749.542763ms
head success,status:200 OK
[[email protected] example01_http_head_request]#
http 常見狀态碼:
http.StatusContinue = 100
http.StatusOK = 200
http.StatusFound = 302
http.StatusBadRequest = 400
http.StatusUnauthorized = 401
http.StatusForbidden = 403
http.StatusNotFound = 404
http.StatusInternalServerError = 500
表單處理:
// 示例代碼:
package main
import (
"io"
"net/http"
)
// 常量 form 是一段 html 代碼
const form = `<html><body><form action="#" method="post" name="bar">
<input type="text" name="in"/>
<input type="text" name="in"/>
<input type="submit" value="Submit"/>
</form></html></body>`
func SimpleServer(w http.ResponseWriter, request *http.Request) { // 請求資訊都在 request 中
io.WriteString(w, "<h1>hello, world</h1>") // 傳回給用戶端一段html代碼
}
func FormServer(w http.ResponseWriter, request *http.Request) {
w.Header().Set("Content-Type", "text/html") // w.Head().Set(key,val) ---> 設定響應頭
switch request.Method { // request.Method --> 請求方法
case "GET":
io.WriteString(w, form) // 把 form 表單傳回給用戶端
case "POST":
request.ParseForm() // 需要先解析表單
io.WriteString(w, request.Form["in"][0]) // request.Form["in"] 是一個數組
io.WriteString(w, "\n")
io.WriteString(w, request.FormValue("in")) // request.FormValue("in") ---> 擷取表單中的值(name重複時,取最近的一個);推薦使用這個
}
}
func main() {
http.HandleFunc("/test1", SimpleServer)
http.HandleFunc("/test2", FormServer)
if err := http.ListenAndServe(":8088", nil); err != nil {
}
}
模闆操作
1) 替換
main.go 檔案内容如下:
// 示例代碼:
package main
import (
"fmt"
"os"
"text/template" // 導入 模闆 包
)
type Person struct {
Name string
age string
}
func main() {
t, err := template.ParseFiles("./index.html") // 解析模闆檔案; t 是模闆對象
if err != nil {
fmt.Println("parse file err:", err)
return
}
p := Person{Name: "Mary", age: "31"} // 結構體對象首字母大寫的字段可以導入到模闆中
if err := t.Execute(os.Stdout, p); err != nil { // t.Execute() --> 執行模闆對象,第一個參數表示輸出到終端,第二個參數表示 導入的結構體對象
fmt.Println("There was an error:", err.Error())
}
}
index.html 代碼如下:
<html>
<head>
// 結構體對象沒有的字段不能導入,要不然會報錯,如下
</head>
<body>
<p>{{.}} </p> // .表示 p 那個對象
<p> hello, {{.Name}}</p> // .Name 表示 p 對象 的Name字段的值 #}
// 首字母小寫的字段也不能在模闆中渲染
</body>
</html>
運作結果:
// 運作結果:
[[email protected] main]# go run main.go
<html>
<head>
// 結構體對象沒有的字段不能導入,要不然會報錯,如下
</head>
<body>
<p>{Mary 31} </p> // .表示 p 那個對象
<p> hello, Mary</p> // .Name 表示 p 對象 的Name字段的值 #}
// 首字母小寫的字段也不能在模闆中渲染
</body>
</html>
[[email protected] main]#
2) if 判斷
main.go 檔案内容:
// 示例代碼:
package main
import (
"fmt"
"text/template" // 導入 模闆 包
"net/http"
)
type Person struct {
Name string
Age int
}
func RenderTemplate(w http.ResponseWriter, request *http.Request){
t, err := template.ParseFiles("./index.html") // 解析模闆檔案; t 是模闆對象
if err != nil {
fmt.Println("parse file err:", err)
return
}
p := Person{Name: "Mary", Age: 31} // 結構體對象首字母大寫的字段可以導入到模闆中
if err := t.Execute(w, p); err != nil { // 模闆寫入到在 http.ResponseWriter 中,傳回給用戶端
fmt.Println("There was an error:", err.Error())
}
}
func main() {
http.HandleFunc("/template",RenderTemplate)
if err := http.ListenAndServe(":8080",nil); err != nil {
}
}
index.html 檔案内容:
<html>
<head>
</head>
<body>
/*
if 文法:
{{if ...}}
{{else}}
{{end}}
*/
{# gt 表示大于 #}
{{if gt .Age 18}}
<p>hello oldman,{{.Name}} </p>
{{else}}
<p>hello young {{.Name}}</p>
{{end}}
</body>
</html>
if常見操作符:
not 非
{{if not .condition}}
{{end}}
and 與
{{if and .condition1 .condition2}}
{{end}}
or 或
{{if or .condition1 .condition2}}
{{end}}
eq 等于
{{if eq .var1 .var2}}
{{end}}
ne 不等于
{{if ne .var1 .var2}}
{{end}}
lt 小于 (less than)
{{if lt .var1 .var2}}
{{end}}
le 小于等于
{{if le .var1 .var2}}
{{end}}
gt 大于
{{if gt .var1 .var2}}
{{end}}
ge 大于等于
{{if ge .var1 .var2}}
{{end}}
模闆中with的用法:
{{with .Var}}
{end}}
示例代碼:
<html>
<head>
</head>
<body>
{{with .Name}} <!-- 通過這行的 with ,. 就代表 Name ;隻有 with 語句中 . 是 Name -->
<p>hello, old man, {{.}}</p>
{{end}}
</body>
</html>
模闆的循環:
{{range.}}
{{end }}
示例代碼:
<html>
<head>
</head>
<body>
<!-- 周遊 變量-->
{{range .}}
{{if gt .Age 18}}
<p>hello, old man, {{.Name}}</p>
{{else}}
<p>hello,young man, {{.Name}}</p>
{{end}}
{{end}}
</body>
</html>
Mysql
建立測試表
CREATE TABLE person (
user_id int primary key auto_increment,
username varchar(260),
sex varchar(260),
email varchar(260)
);
CREATE TABLE place (
country varchar(200),
city varchar(200),
telcode int
);
安裝連接配接資料庫的第三方包:
go get -u github.com/go-sql-driver/mysql // 安裝 mysql 驅動
go get github.com/jmoiron/sqlx
連結mysql:
// 先在 資料庫主機上配置設定權限,如下:
mysql> grant all privileges on gotest.* to 'root'@'172.16.1.%' identified by '123456';
mysql> flush privileges;
// 代碼運作伺服器内網位址: 172.16.1.122
database, err := sqlx.Open("mysql", "root:[email protected](172.16.1.51:3306)/gotest")
// 參數說明:
// "mysql" ---> 資料庫類型
// root ---> 使用者名
// 123456 ---> 密碼
// tcp ---> 連接配接協定
// 172.16.1.50 ---> 資料庫主機位址
// 3306 ---> 端口
// gotest ---> 資料庫名稱
go 資料庫的增删改查
insert操作
r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "stu001", "man", "[email protected]") // ? 是占位符
示例代碼:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql" // _ 表示隻是把這個庫引進來做初始化,但并不直接引用這個庫
"github.com/jmoiron/sqlx" // sqlx 在 mysql 驅動的層面上又做了封裝,會更好用些
)
type Person struct {
UserId int `db:"user_id"` // tag 就是資料庫中的列名
Username string `db:"username"`
Sex string `db:"sex"`
Email string `db:"email"`
}
type Place struct {
Country string `db:"country"`
City string `db:"city"`
TelCode int `db:"telcode"`
}
var Db *sqlx.DB // Db 就代表一個資料庫;Db 這個變量是線程安全的,因為其内部已經内置實作了一個 連接配接池
func init() { // init() 函數在 main 函數之前自動執行
database, err := sqlx.Open("mysql", "root:[email protected](172.16.1.51:3306)/gotest") // database 是一個資料庫執行個體
if err != nil {
fmt.Println("open mysql failed,", err)
return
}
Db = database
}
func main() {
r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "stu001", "man", "[email protected]")
if err != nil {
fmt.Println("exec failed, ", err)
return
}
id, err := r.LastInsertId() // 剛插入的那條記錄的 id
if err != nil {
fmt.Println("exec failed, ", err)
return
}
fmt.Println("insert succ:", id)
}
Select 操作
err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1)
示例代碼:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
type Person struct {
UserId int `db:"user_id"`
Username string `db:"username"`
Sex string `db:"sex"`
Email string `db:"email"`
}
type Place struct {
Country string `db:"country"`
City string `db:"city"`
TelCode int `db:"telcode"`
}
var Db *sqlx.DB
func init() {
database, err := sqlx.Open("mysql", "root:[email protected](172.16.1.51:3306)/gotest")
if err != nil {
fmt.Println("open mysql failed,", err)
return
}
Db = database
}
func main() {
var person []Person
err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1) // 從資料庫中查詢出來結果會自動填充到 person 這個結構體中
if err != nil {
fmt.Println("exec failed, ", err)
return
}
fmt.Println("select succ:", person)
}
// 運作結果:
[[email protected] example02_mysql_select]# go run main/main.go
select succ: [{1 stu001 man [email protected]}]
[[email protected] example02_mysql_select]#
update操作
_, err := Db.Exec("update person set username=? where user_id=?", "stu0001", 1)
示例代碼:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
type Person struct {
UserId int `db:"user_id"`
Username string `db:"username"`
Sex string `db:"sex"`
Email string `db:"email"`
}
type Place struct {
Country string `db:"country"`
City string `db:"city"`
TelCode int `db:"telcode"`
}
var Db *sqlx.DB
func init() {
database, err := sqlx.Open("mysql", "root:[email protected](172.16.1.51:3306)/gotest")
if err != nil {
fmt.Println("open mysql failed,", err)
return
}
Db = database
}
func main() {
_, err := Db.Exec("update person set username=? where user_id=?", "stu0001", 1) // 更新操作
if err != nil {
fmt.Println("exec failed, ", err)
return
}
}
Delete 操作
_, err := Db.Exec("delete from person where user_id=?", 1)
示例代碼:
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
type Person struct {
UserId int `db:"user_id"`
Username string `db:"username"`
Sex string `db:"sex"`
Email string `db:"email"`
}
type Place struct {
Country string `db:"country"`
City string `db:"city"`
TelCode int `db:"telcode"`
}
var Db *sqlx.DB
func init() {
database, err := sqlx.Open("mysql", "root:[email protected](172.16.1.51:3306)/gotest")
if err != nil {
fmt.Println("open mysql failed,", err)
return
}
Db = database
}
func main() {
_, err := Db.Exec("delete from person where user_id=?", 1)
if err != nil {
fmt.Println("exec failed, ", err)
return
}
fmt.Println("delete succ")
}
轉載于:https://www.cnblogs.com/neozheng/p/11355592.html