http编程

) Go原生支持 http : import ("net/http")
) Go 的 http 服务性能和 nginx 比较接近
) 几行代码就可以实现一个 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))
} // 运行结果:
[root@NEO 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>
[root@NEO example01_http_client]#

http常见请求方法

)Get请求
)Post请求
)Put请求
)Delete请求
)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 --> 状态码
}
} // 运行结果:
[root@NEO example01_http_head_request]# go run main/main.go
head success,status: 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: OK
[root@NEO 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 * // 自定义超时时间
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 --> 状态码
}
} // 运行结果:
[root@NEO example01_http_head_request]# go run main/main.go
interval: .062376ms
head success,status: OK
interval: .000789206s
head http://www.google.com failed,err:Head http://www.google.com: dial tcp 69.63.184.142:80: i/o timeout
interval: .542763ms
head success,status: OK
[root@NEO example01_http_head_request]#

http 常见状态码:

http.StatusContinue =
http.StatusOK =
http.StatusFound =
http.StatusBadRequest =
http.StatusUnauthorized =
http.StatusForbidden =
http.StatusNotFound =
http.StatusInternalServerError =

表单处理:

// 示例代码:
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"][]) // 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: ""} // 结构体对象首字母大写的字段可以导入到模板中
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>

运行结果:

// 运行结果:
[root@NEO main]# go run main.go
<html>
<head>
// 结构体对象没有的字段不能导入,要不然会报错,如下
</head>
<body>
<p>{Mary } </p> // .表示 p 那个对象
<p> hello, Mary</p> // .Name 表示 p 对象 的Name字段的值 #}
// 首字母小写的字段也不能在模板中渲染
</body>
</html>
[root@NEO 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: } // 结构体对象首字母大写的字段可以导入到模板中
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 '';
mysql> flush privileges;
// 代码运行服务器内网地址: 172.16.1.122 database, err := sqlx.Open("mysql", "root:123456@tcp(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", "stu01@qq.com")        // ? 是占位符

示例代码:

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:123456@tcp(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", "stu01@qq.com") 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=?", )

示例代码:

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:123456@tcp(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=?", ) // 从数据库中查询出来结果会自动填充到 person 这个结构体中
if err != nil {
fmt.Println("exec failed, ", err)
return
} fmt.Println("select succ:", person)
} // 运行结果:
[root@NEO example02_mysql_select]# go run main/main.go
select succ: [{ stu001 man stu01@qq.com}]
[root@NEO example02_mysql_select]#

update操作

_, err := Db.Exec("update person set username=? where user_id=?", "stu0001", )

示例代码:

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:123456@tcp(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", ) // 更新操作
if err != nil {
fmt.Println("exec failed, ", err)
return
} }

Delete 操作

_, err := Db.Exec("delete from person where user_id=?", )

示例代码:

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:123456@tcp(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=?", )
if err != nil {
fmt.Println("exec failed, ", err)
return
} fmt.Println("delete succ")
}

最新文章

  1. Google Java编程库Guava介绍
  2. 源码阅读系列:EventBus
  3. Java用来进行批量文件重命名,批量提取特定类型文件
  4. bind绑定事件,摁回车键提交查询,点击查询也可以提交查询
  5. Linux基础精华
  6. mongodb备份恢复
  7. iOS开发过程中,触控板的使用技巧
  8. python 字符串 大小写转换
  9. hdu 4850 Wow! Such String! 欧拉回路
  10. Alternating Current
  11. codeforces 339C Xenia and Weights(dp或暴搜)
  12. Linux在高铁项目的部署环境
  13. UVa 514 Rails(经典栈)
  14. DOM简要
  15. attr与prop的区别
  16. 启动Mysql报错:Another MySQL daemon already running with the same unix socket.
  17. JAVA物联网九大核心热点技术
  18. Webpack 4教程 - 第七部分 减少打包体积与Tree Shaking
  19. SkyWalking
  20. Java基础(变量数&amp;常量&amp;据类型&amp;类型转换)

热门文章

  1. ios 报错记录
  2. docker安装和基本命令
  3. Hibernate3运行原理
  4. NLP之电影评分数据的情感分析
  5. Djang之ModelForm组件的简单使用
  6. 小D课堂 - 新版本微服务springcloud+Docker教程_6-05 高级篇幅之高并发情况下
  7. java文件上传系统
  8. python matlab 带包实现全排列
  9. 安装flanal报错解决
  10. Spring Boot Lombok配置