Go语言系列- http编程和mysql
http编程
一、Http协议
1. 什么是协议?
协议,是指通信的双方,在通信流程或内容格式上,共同遵守的标准。
2. 什么是http协议?
http协议,是互联网中最常见的网络通信标准。
3. http协议的特点
①通信流程:断开式(无状态)
断开式:http协议每次响应完成后,会断开与客户端的连接
无状态:由于服务器断开了之前的连接,就无法知晓连接间的关系
②内容格式:消息头和消息体
二、http编程概述
HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最为广泛的一种网络协议,定义了客户端和服务端之间请求和响应的传输标准。Go语言标准库内建提供了net/http包,涵盖了HTTP客户端和服务端的具体实现。使用net/http包,我们可以很方便地编写HTTP客户端或服务端的程序。
特点:
a. Go原生支持http,import(“net/http”)
b. Go的http服务性能和nginx比较接近
c. 几行代码就可以实现一个web服务
三、客户端与服务端
1. 服务端
package main import (
"fmt"
"net/http"
) //w, 给客户端回复数据
//r, 读取客户端发送的数据
func HandConn(w http.ResponseWriter, r *http.Request) {
fmt.Println("r.Method = ", r.Method)
fmt.Println("r.URL = ", r.URL)
fmt.Println("r.Header = ", r.Header)
fmt.Println("r.Body = ", r.Body) w.Write([]byte("hello go")) //给客户端回复数据
} func main() {
//注册处理函数,用户连接,自动调用指定的处理函数
http.HandleFunc("/", HandConn) //监听绑定
http.ListenAndServe(":8000", nil)
}
package main import (
"fmt"
"net/http"
) func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Println("r.Method = ", r.Method)
fmt.Println("r.URL = ", r.URL)
fmt.Println("r.Header = ", r.Header)
fmt.Println("r.Body = ", r.Body)
fmt.Println("handle hello")
fmt.Fprintf(w, "hello ")
} func login(w http.ResponseWriter, r *http.Request) {
fmt.Println("handle login")
fmt.Fprintf(w, "login ")
} func history(w http.ResponseWriter, r *http.Request) {
fmt.Println("handle history")
fmt.Fprintf(w, "history ")
} func main() {
http.HandleFunc("/", Hello)
http.HandleFunc("/user/login", login)
http.HandleFunc("/user/history", history)
err := http.ListenAndServe("0.0.0.0:8880", nil)
if err != nil {
fmt.Println("http listen failed")
}
}
http_server.go
2. 客户端
package main import (
"fmt"
"net/http"
) func main() {
//resp, err := http.Get("http://www.baidu.com")
resp, err := http.Get("http://127.0.0.1:8000")
if err != nil {
fmt.Println("http.Get err = ", err)
return
} defer resp.Body.Close() fmt.Println("Status = ", resp.Status)
fmt.Println("StatusCode = ", resp.StatusCode)
fmt.Println("Header = ", resp.Header)
//fmt.Println("Body = ", resp.Body) buf := make([]byte, 4*1024)
var tmp string for {
n, err := resp.Body.Read(buf)
if n == 0 {
fmt.Println("read err = ", err)
break
}
tmp += string(buf[:n])
} //读取网页内容,打印出来
fmt.Println("tmp = ", tmp)
}
package main import (
"fmt"
"io/ioutil"
"net/http"
) func main() {
res, err := http.Get("https://www.baidu.com/")
if err != nil {
fmt.Println("get err:", err)
return
} data, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("get data err:", err)
return
} fmt.Println(string(data))
}
http_client.go
四、http常见请求方法
- 1、OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
- 2、HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
- 3、GET
向特定的资源发出请求。它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。
- 4、POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
- 5、PUT
向指定资源位置上传其最新内容
- 6、DELETE
请求服务器删除Request-URL所标识的资源
- 7、TRACE
回显服务器收到的请求,主要用于测试或诊断
- 8、CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
注意:
- 1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。
- 2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的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
常见状态码
get 和 post区别
区别:
get请求无消息体,只能携带少量数据
post请求有消息体,可以携带大量数据
携带数据的方式:
get请求将数据放在url地址中
post请求将数据放在消息体中
GET请求请提交的数据放置在HTTP请求协议头中,而POST提交的数据则放在实体数据中;
GET方式提交的数据最多只能有1024字节,而POST则没有此限制。
五、Head请求
package main import (
"fmt"
"net/http"
"net"
"time"
) var url = []string{
"http://www.baidu.com",
"http://google.com",
"http://taobao.com",
} func main() { for _, v := range url {
c := http.Client{
Transport: &http.Transport {
Dial:func(network, addr string) (net.Conn, error){
timeout := time.Second*2
return net.DialTimeout(network, addr, timeout)
},
},
}
resp, err := c.Head(v)
if err != nil {
fmt.Printf("head %s failed, err:%v\n", v, err)
continue
} fmt.Printf("head succ, status:%v\n", resp.Status)
}
}
六、表单及panic处理
package main import (
"io"
"log"
"net/http"
) 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></body></html>` func SimpleServer(w http.ResponseWriter, request *http.Request) {
io.WriteString(w, "<h1>hello, world</h1>")
panic("test test")
} func FormServer(w http.ResponseWriter, request *http.Request) {
w.Header().Set("Content-Type", "text/html")
switch request.Method {
case "GET":
io.WriteString(w, form)
case "POST":
request.ParseForm()
io.WriteString(w, request.Form["in"][1])
io.WriteString(w, "\n")
io.WriteString(w, request.FormValue("in"))
}
}
func main() {
http.HandleFunc("/test1", logPanics(SimpleServer))
http.HandleFunc("/test2", logPanics(FormServer))
if err := http.ListenAndServe(":8088", nil); err != nil {
}
} func logPanics(handle http.HandlerFunc) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
defer func() {
if x := recover(); x != nil {
log.Printf("[%v] caught panic: %v", request.RemoteAddr, x)
}
}()
handle(writer, request)
}
}
七、模板
1. 替换 {{.字段名}}
- if 判断
- if 常见操作
- {{.}}
- {{with .Var}}... {{end}}
2. 循环
{{range.}}... {{end}}
模板示例1:
package main import (
"fmt"
"os"
"text/template"
) type Person struct {
Name string
Title string
age string
} func main() {
t, err := template.ParseFiles("day10/template/index.html")
if err != nil {
fmt.Println("parse file err:", err)
return
}
p := Person{Name: "Mary", age: "31", Title: "我的个人网站"}
if err := t.Execute(os.Stdout, p); err != nil {
fmt.Println("There was an error:", err.Error())
}
}
main.go
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<p> hello, {{.Name}}</p>
<p> {{.}}</p>
</body>
</html>
index.html
<html>
<head>
<title>我的个人网站</title>
</head>
<body>
<p> hello, Mary</p>
<p> {Mary 我的个人网站 31}</p>
</body>
</html>
模板示例2
package main import (
"fmt"
"html/template"
"io"
"net/http"
) var myTemplate *template.Template type Result struct {
output string
} func (p *Result) Write(b []byte) (n int, err error) {
fmt.Println("called by template")
p.output += string(b)
return len(b), nil
} type Person struct {
Name string
Title string
Age int
} func userInfo(w http.ResponseWriter, r *http.Request) {
fmt.Println("handle hello")
//fmt.Fprintf(w, "hello ")
var arr []Person
p := Person{Name: "Mary001", Age: 10, Title: "我的个人网站"}
p1 := Person{Name: "Mary002", Age: 10, Title: "我的个人网站"}
p2 := Person{Name: "Mary003", Age: 10, Title: "我的个人网站"}
arr = append(arr, p)
arr = append(arr, p1)
arr = append(arr, p2) resultWriter := &Result{}
io.WriteString(resultWriter, "hello world")
err := myTemplate.Execute(w, arr)
if err != nil {
fmt.Println(err)
}
fmt.Println("template render data:", resultWriter.output)
//myTemplate.Execute(w, p)
//myTemplate.Execute(os.Stdout, p)
//file, err := os.OpenFile("C:/test.log", os.O_CREATE|os.O_WRONLY, 0755)
//if err != nil {
// fmt.Println("open failed err:", err)
// return
//} } func initTemplate(filename string) (err error) {
myTemplate, err = template.ParseFiles(filename)
if err != nil {
fmt.Println("parse file err:", err)
return
}
return
} func main() {
initTemplate("day10/template_http/index.html")
http.HandleFunc("/user/info", userInfo)
err := http.ListenAndServe("0.0.0.0:8880", nil)
if err != nil {
fmt.Println("http listen failed")
}
}
main.go
<html>
<head>
</head>
<body>
<p>hello world</p>
<table border="1">
{{range .}}
<tr>
<td>{{.Name}}</td> <td>{{.Age}}</td><td>{{.Title}}</td>
</tr>
{{end}}
</table>
</body>
</html>
index.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
)
1. 连接mysql
database, err := sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
2. 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"
) 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:0000@tcp(127.0.0.1:3306)/test")
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()
if err != nil {
fmt.Println("exec failed, ", err)
return
} fmt.Println("insert succ:", id)
}
mysql_insert
3. 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:0000@tcp(127.0.0.1:3306)/test")
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)
if err != nil {
fmt.Println("exec failed, ", err)
return
} fmt.Println("select succ:", person)
}
mysql_select
4. 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:0000@tcp(127.0.0.1:3306)/test")
if err != nil {
fmt.Println("open mysql failed,", err)
return
} Db = database
} func main() { _, err := Db.Exec("update person set username=? where user_id=?", "stu0003", 1)
if err != nil {
fmt.Println("exec failed, ", err)
return
} }
mysql_update
5. 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:0000@tcp(127.0.0.1:3306)/test")
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")
}
mysql_delete
Go语言系列- http编程和mysql的更多相关文章
- Go语言系列- Socket编程和Redis
Socket编程 一.socket编程概述 什么是socket编程? socket编程是计算机PC机器上2个程序通过一个双向的通信连接实现数据的交互,这个连接的一端就是一个socket.socket的 ...
- Python语言系列-09-socket编程
简介 软件开发的架构 1.C/S架构(client-server) 2.B/S架构 (browser-server) 网络基础概念 网络三要素: 1.ip 2.port 3.通信协议:TCP.UDP ...
- 【转】VxWorks中高精度实时时钟的实现及C语言汇编混合编程
最近一个项目中需要在VxWorks下使用一个高精度实时时钟,要求精度为1ms,溢 出时间大于5小时.VxWorks提供系统时钟,该时钟在操作系统启动后开始计数,精度为1个tick,可以通过tickGe ...
- C语言嵌入式系统编程修炼
C语言嵌入式系统编程修炼 2008-08-19 作者:宋宝华 来源:天极网 C语言嵌入式系统编程修炼之背景篇 本文的讨论主要围绕以通用处理器为中心的协议处理模块进行,因为它更多地牵涉到具体的C语言编程 ...
- openresty开发系列28--openresty中操作mysql
openresty开发系列28--openresty中操作mysql Mysql客户端 应用中最常使用的就是数据库了,尤其mysql数据库,那openresty lua如何操作mysql呢? ...
- curl库 c语言的curl 编程
c语言的curl 编程 [Linux@centos-64-min exercise]# gcc -Wall -o curltest curltest.c /tmp/ccosVANi.o: In fun ...
- 试读《JavaScript语言精髓与编程实践》
有幸看到iteye的活动,有幸读到<JavaScript语言精髓与编程实践_第2版>的试读版本,希望更有幸能完整的读到此书. 说来读这本书的冲动,来得很诡异,写一篇读后感,赢一本书,其实奖 ...
- Windows下C语言的Socket编程例子(TCP和UDP)
原文:Windows下C语言的Socket编程例子(TCP和UDP) 刚刚学windows编程,所以想写学习笔记,这是一个简单的Socket程序例子,开发环境是vc6: 首先是TCP server端: ...
- 《JavaScript语言精髓与编程实践》读书笔记
JavaScript语言精髓与编程实践读书笔记 function v1(v1){ v1 = 100; alert('v1:'+v1); } function v2(name){ v1.apply(th ...
随机推荐
- 网络协议之:还在用HTTP代理?弱爆了!快试试SOCKS5
目录 简介 为什么要使用SOCKS SOCKS5 SOCKS5的使用 总结 简介 存在即是合理,SOCKS5的出现是为了解决SOCKS4中不支持身份认证的大问题而出现的,毕竟大家对网络中的安全越来越重 ...
- RocketMQ架构原理解析(三):消息索引
一.概述 "索引"一种数据结构,帮助我们快速定位.查询数据 前文我们梳理了消息在Commit Log文件的存储过程,讨论了消息的落盘策略,然而仅仅通过Commit Log存储消息是 ...
- 基于Github Actions + Docker + Git 的devops方案实践教程
目录 为什么需要Devops 如何实践Devops 版本控制工具(Git) 学习使用 配置环境 源代码仓库 一台配置好环境的云服务器 SSH远程登录 在服务器上安装docker docker技术准备工 ...
- dart系列之:浏览器中的舞者,用dart发送HTTP请求
目录 简介 发送GET请求 发送post请求 更加通用的操作 总结 简介 dart:html包为dart提供了构建浏览器客户端的一些必须的组件,之前我们提到了HTML和DOM的操作,除了这些之外,我们 ...
- 前端浅谈---协议相关(TCP连接)
TCP连接 http的描述里面,我弱化了交互过程的描述,因为它相对复杂.所以我在此单独描述.客户端和服务端传递数据时过程相对谨慎和复杂,主要是开始和结束的过程.而这整个过程就是TCP连接.连接流程大体 ...
- HyperSnips:VSCode上的自动补全神器
发现一个小众但是巨好用的VSCode自动补全插件:HyperSnips. 作者显然受到了 这位小哥 的启发,将 Vim Ultisnips 的大部分功能搬到了VSCode上.并用 JavaScript ...
- 资源分享 | PyTea:不用运行代码,静态分析pytorch模型的错误
前言 本文介绍一个Pytorch模型的静态分析器 PyTea,它不需要运行代码,即可在几秒钟之内扫描分析出模型中的张量形状错误.文末附使用方法. 本文转载自机器之心 编辑:CV技 ...
- Semaphore信号量源码解析
介绍 Semaphore是什么 Semaphore可以称为信号量,这个原本是操作系统中的概念,是一种线程同步方法,配合PV操作实现线程之间的同步功能.信号量可以表示操作系统中某种资源的个数,因此可以用 ...
- [源码解析] PyTorch 分布式之弹性训练(3)---代理
[源码解析] PyTorch 分布式之弹性训练(3)---代理 目录 [源码解析] PyTorch 分布式之弹性训练(3)---代理 0x00 摘要 0x01 总体背景 1.1 功能分离 1.2 Re ...
- Mybatis批量插入写法
<insert id="insertBatchList"> INSERT INTO tag ( `tag_name`, `tag_weight`, ) VALUES & ...