继第一篇Python篇,这是第二篇GoLang篇,通过Go设这web server
设置服务端监听,等待客户端请求;处理客户端请求,查询数据库,生成返回结果,发送给客户端.
从官网下载对应系统的安装包
安装完成,设置好环境变量
输入"go version",如果显示相应的go版本,则安装完成
zxl@zxl:~$ go version
go version go1.12 linux/amd64
新建好go的工作空间根目录,将该目录设置为GOPATH
以linux为例
export GOPATH=/home/zxl/workspace/my_github/go_test_server
通过下载链接选择最新版本,下载对应系统的安装包
打开LitelDE,选择菜单"工具"—>“编辑当前环境”,设置好GOROOT,GOPATH,PATH
GOROOT=/usr/local/go
GOPATH=/home/zxl/workspace/my_github/go_test_server
PATH=$GOROOT/bin:$PATH
也可以选择菜单"工具"—>"管理GOPATH/Modules"设置每个工作控件的GOPATH
接口主要响应客户端数据请求
如下代码所示,设置了端口为"9090"的服务,点击菜单"编译"—>“BuildAndRun”,则可以启动服务
在浏览器输入"http://localhost:9090/test",网页则显示"Hello astaxie!"
package main
import (
"fmt"
"log"
"net/http"
"strings"
http_handle "http_handle"
)
func sayhelloName(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //解析参数,默认是不会解析的
fmt.Println(r.Form) //这些信息是输出到服务器端的打印信息
fmt.Println("path", r.URL.Path)
fmt.Println("scheme", r.URL.Scheme)
fmt.Println(r.Form["url_long"])
for k, v := range r.Form {
fmt.Println("key:", k)
fmt.Println("val:", strings.Join(v, ""))
}
fmt.Fprintf(w, "Hello astaxie!") //这个写入到w的是输出到客户端的
}
func main() {
http.HandleFunc("/test", sayhelloName) //设置访问的路由
err := http.ListenAndServe(":9090", nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
package data
type QsbkHotPicItem struct {
Id string
AuthorNickName string
AuthorGender string
AuthorAge string
AuthorImgUrl string
Content string
ThumbImgUrl string
StatsVoteContent string
StatsCommentContent string
StatsCommentDetailUrl string
Md5 string
}
type QsbkHotPicItemList struct {
ItemList []QsbkHotPicItem
}
package base_db
import (
"database/sql"
"fmt"
_ "github.com/Go-SQL-Driver/MySQL"
)
func Query(sql_str string) (*sql.Rows, *sql.Stmt, *sql.DB) {
fmt.Println("query::sql_str = ", sql_str)
db, _ := sql.Open("mysql", "用户名:密码@tcp(zxltest.zicp.vip:42278)/joke")
fmt.Println("query::open_db_err = ", open_db_err)
stmt, prepare_err := db.Prepare(sql_str)
fmt.Println("query::prepare_err = ", prepare_err)
rows, query_err := stmt.Query()
fmt.Println("query::query_err = ", query_err)
return rows, stmt, db
}
以MySQL为例,导入数据库驱动
在命令行终端,输入go get -u github.com/go-sql-driver/mysql
匿名导入包_ "github.com/Go-SQL-Driver/MySQL"
导入数据解构"data"
导入数据库操作base_db "db"
其会自动下载驱动库,并放入到设置的GOPATH目录下
这样就可以完成代码开发,最后以json形式把数据返回给客户端
package http_handle
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"strings"
_ "github.com/Go-SQL-Driver/MySQL"
"data"
base_db "db"
)
func QsbkHotPicList(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //解析参数,默认是不会解析的
fmt.Println(r.Form) //这些信息是输出到服务器端的打印信息
fmt.Println("path", r.URL.Path)
fmt.Println("scheme", r.URL.Scheme)
var last_id = -1
if len(r.Form["last_id"]) > 0 {
last_id, _ = strconv.Atoi(r.Form["last_id"][0])
}
page, _ := strconv.Atoi(r.Form["page"][0])
page_size, _ := strconv.Atoi(r.Form["page_size"][0])
fmt.Println("last_id", last_id)
fmt.Println("page", page)
fmt.Println("page_size", page_size)
var start_index = page * page_size
var end_index = page_size
fmt.Println("start_index", start_index)
fmt.Println("end_index", end_index)
for k, v := range r.Form {
fmt.Println("key:", k)
fmt.Println("val:", strings.Join(v, ""))
}
var sql_where = ""
if last_id > 0 {
start_index = 0
end_index = 10
sql_where = " WHERE id < " + strconv.Itoa(last_id) + " "
}
fmt.Println("sql_where", sql_where)
var sql_str = "SELECT " +
"id, author_nick_name,author_gender,author_age,author_img_url,content,thumb_img_url,stats_vote_content,stats_comment_content,stats_comment_detail_url,md5 " +
"FROM joke " + sql_where +
"ORDER BY id DESC LIMIT " + strconv.Itoa(start_index) + "," + strconv.Itoa(end_index)
rows, stmt, db := base_db.Query(sql_str)
var qsbkHotPicItemList data.QsbkHotPicItemList
for rows.Next() {
var id, author_nick_name, author_gender, author_age, author_img_url, content, thumb_img_url, stats_vote_content, stats_comment_content, stats_comment_detail_url, md5 string
rows.Scan(&id, &author_nick_name, &author_gender, &author_age, &author_img_url, &content, &thumb_img_url, &stats_vote_content, &stats_comment_content, &stats_comment_detail_url, &md5)
fmt.Println("query::result = ", id, author_nick_name, author_gender, author_age, author_img_url, content, thumb_img_url, stats_vote_content, stats_comment_content, stats_comment_detail_url, md5)
var item = data.QsbkHotPicItem{id, author_nick_name, author_gender, author_age, author_img_url, content, thumb_img_url, stats_vote_content, stats_comment_content, stats_comment_detail_url, md5}
qsbkHotPicItemList.ItemList = append(qsbkHotPicItemList.ItemList, item)
}
defer rows.Close()
defer stmt.Close()
defer db.Close()
responseResult, responseError := json.Marshal(qsbkHotPicItemList)
fmt.Println("query::responseError = ", responseError)
fmt.Println("query::responseResult = ", string(responseResult))
fmt.Fprint(w, string(responseResult))
}
由于我们当前调试都是本地局域网络,别人是访问不了我们的服务,因此我们需要提供外网功能,即内网穿透
可以通过花生壳教程完成内网穿透设置
最后将我们的端口为"9090"的服务启动,再开启花生壳内网穿透设置,就可以提供外网功能了