您的位置:首页 > 编程语言 > Go语言

golang实战--实现短地址服务

2017-04-11 15:40 555 查看
golang写的简单的短地址服务,只做练手用,还有很多不完善的地方

TODO:

验证URL的有效性;

确认URL的协议(http、https)

数据库操作优化

现在的路由太简单了

下面贴上代码

package main

import (
"database/sql"
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
_ "github.com/go-sql-driver/mysql"
)

var elements = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var db *sql.DB

type returnData struct {
ShortUrl string
LongUrl string
}

//这里首字母一定要大写
//json数据与struct字段相匹配时,会查找与json中key相同的可导出字段(首字母大写)
type postData struct {
LongUrl string
}

func main()  {
Init()
http.HandleFunc("/", simpleRoute)
err := http.ListenAndServe(":9090", nil)
if err != nil {
panic(err)
}
}

func Init()  {
db, _ = sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/shortener")
//defer db.Close()
}

//十进制转换成62进制
func base10ToBase62(n int64) string {
var str string
for n != 0 {
str += string(elements[n % 62])
n /= 62
}

for len(str) != 5 {
str += "0"
}
return str
}

func buildResponse(p postData) returnData {
stmtIns, err := db.Prepare("INSERT INTO urls VALUES (null, '', ?, 0)")
if err != nil {
panic(err.Error())
}
defer stmtIns.Close()

result, err := stmtIns.Exec(p.LongUrl)
if err != nil {
panic(err.Error())
}
id, _ := result.LastInsertId()
shorter := base10ToBase62(id)

stmtUps, err := db.Prepare("UPDATE urls SET short_url=? WHERE id=?")
if err != nil {
panic(err.Error())
}
defer stmtUps.Close()

stmtUps.Exec(shorter, id)

var returns returnData
returns.LongUrl = p.LongUrl
returns.ShortUrl = shorter
return  returns
}

func shortUri(w http.ResponseWriter, r *http.Request)  {
defer r.Body.Close()
var p postData
data, _ := ioutil.ReadAll(r.Body)
json.Unmarshal(data, &p)
returnData := buildResponse(p)
returnData.ShortUrl = "http://" + r.Host + "/"+ returnData.ShortUrl
jsonData, err := json.Marshal(returnData)
if err != nil {
fmt.Println("json error:", err)
}
w.Write([]byte(jsonData))
}

func simpleRoute(w http.ResponseWriter, r *http.Request)  {
urlPath := r.URL.Path
if len(urlPath) == 6 {
redirectUrl(w, r)
} else if urlPath == "/shortener" {
shortUri(w, r)
} else {
w.WriteHeader(404)
}
}

func redirectUrl(w http.ResponseWriter, r *http.Request)  {
urlPath := r.URL.Path
rs := []rune(urlPath)
urlPath = string(rs[1:])
stmtOut, err := db.Prepare("SELECT long_url FROM urls WHERE short_url=?")
if err != nil {
panic(err.Error())
}
defer stmtOut.Close()

var url string
err = stmtOut.QueryRow(urlPath).Scan(&url)
if err != nil {
panic(err.Error())
}
http.Redirect(w, r, "http://" + url, 301)
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  golang
相关文章推荐