通过Beego将之前实现的短url项目实现
时间:2022-05-06
本文章向大家介绍通过Beego将之前实现的短url项目实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
正好通过这个小例子对之前了解的beego框架的基本内容进行一个简单的应用
实现的完整代码地址:https://github.com/pythonsite/go_simple_code/tree/master/beego_short_url
数据库没有什么变化,还是和之前一样,主要是把处理逻辑放到beego中就可以了
代码的主要目录为:
localhost:beego_short_url zhaofan$ tree
.
├── beego_short_url
├── conf
│ └── app.conf
├── controllers
│ ├── default.go
│ └── short_url.go
├── main.go
├── models
│ └── data.go
├── routers
│ └── router.go
├── static
│ ├── css
│ ├── img
│ └── js
│ └── reload.min.js
├── tests
│ └── default_test.go
└── views
└── index.tpl
10 directories, 10 files
关于长短url相互转换的的请求和返回定义的struct在models下的data中,代码为:
package models
type Long2ShortRequest struct {
OriginUrl string `json:"origin_url"`
}
type ResponseHeader struct {
Code int `json:"code"`
Message string `json:"message"`
}
type Long2ShortResponse struct {
ResponseHeader
ShortUrl string `json:"short_url"`
}
type Short2LongRequest struct {
ShortUrl string `json:"short_url"`
}
type Short2LongResponse struct {
ResponseHeader
OriginUrl string `json:"origin_url"`
}
type ShortUrl struct {
ShortUrl string `json:"short_url" db:"short_url"`
}
而将原来在logic中的处理逻辑都放到了controllers中的short_url文件中
package controllers
import (
"github.com/astaxie/beego"
"beego_short_url/models"
"encoding/json"
"database/sql"
"crypto/md5"
"github.com/jmoiron/sqlx"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
var (
Db *sqlx.DB
)
func InitDb()(err error){
Db, err = sqlx.Open("mysql",beego.AppConfig.String("Db::dsn"))
if err != nil{
beego.Error("connect to mysql failed:",err)
return
}
return
}
type ShortUrl struct {
Id int64 `db:"id"`
ShortUrl string `db:"short_url"`
OriginUrl string `db:"origin_url"`
HashCode string `db:"hash_code"`
}
type ShortUrlController struct {
beego.Controller
}
func (c *ShortUrlController) Jump() {
shortUrl := c.GetString("shorturl")
if len(shortUrl) == 0{
return
}
var req models.Short2LongRequest
var resp *models.Short2LongResponse = &models.Short2LongResponse{}
defer func(){
if err := recover();err != nil{
beego.Error("panic err:",err)
//resp.Code = 500
//resp.Message = "server busy"
//c.Data["json"] = resp
//c.ServeJSON()
return
}
}()
req.ShortUrl = shortUrl
resp,err := Short2Long(&req)
if err != nil{
beego.Error("short2Long failed error:",err)
return
}
beego.Info("origin url:%s short url:%s",resp.OriginUrl,shortUrl)
c.Redirect(resp.OriginUrl,301)
}
func (c *ShortUrlController) ShortUrlList() {
limit,err := c.GetInt("limit")
if err != nil{
beego.Warn("not have limit params use default 10")
limit = 10
}
data,err := GetLastShortUrl(limit)
if err != nil{
beego.Error("from db get url list error:",err)
}
for i,v:= range data{
v.ShortUrl = fmt.Sprintf("/jump/?shorturl=%s",v.ShortUrl)
data[i] = v
}
c.Data["url_list"] = data
c.TplName = "index.tpl"
}
func(c *ShortUrlController) Long2Short(){
var req models.Long2ShortRequest
var resp *models.Long2ShortResponse = &models.Long2ShortResponse{}
defer func(){
if err := recover();err != nil{
beego.Error("panic err:",err)
resp.Code = 500
resp.Message = "server busy"
c.Data["json"] = resp
c.ServeJSON()
return
}
}()
err := json.Unmarshal(c.Ctx.Input.RequestBody,&req)
if err != nil{
beego.Error("unmarshal failed,err:",err)
resp.Code = 1001
resp.Message = "json unmarshal failed"
c.Data["json"] = resp
c.ServeJSON()
return
}
resp,err = Long2Short(&req)
if err != nil{
beego.Error("long2short failed,err:",err)
resp.Code = 1002
resp.Message = "long2short failed"
c.Data["json"] = resp
c.ServeJSON()
return
}
c.Data["json"] = resp
c.ServeJSON()
}
func(c *ShortUrlController) Short2Long(){
var req models.Short2LongRequest
var resp *models.Short2LongResponse = &models.Short2LongResponse{}
defer func(){
if err := recover();err != nil{
beego.Error("panic err:",err)
resp.Code = 500
resp.Message = "server busy"
c.Data["json"] = resp
c.ServeJSON()
return
}
}()
err := json.Unmarshal(c.Ctx.Input.RequestBody,&req)
if err != nil{
beego.Error("unmarshal failed,err:",err)
resp.Code = 1001
resp.Message = "json unmarshal failed"
c.Data["json"] = resp
c.ServeJSON()
return
}
resp,err = Short2Long(&req)
if err != nil{
beego.Error("Short2Long failed,err:",err)
resp.Code = 1002
resp.Message = "long2short failed"
c.Data["json"] = resp
c.ServeJSON()
return
}
c.Data["json"] = resp
c.ServeJSON()
}
func Long2Short(req *models.Long2ShortRequest) (response *models.Long2ShortResponse, err error) {
response = &models.Long2ShortResponse{}
urlMd5 := fmt.Sprintf("%x",md5.Sum([]byte(req.OriginUrl)))
var short ShortUrl
err = Db.Get(&short,"select id,short_url,origin_url,hash_code from short_url where hash_code=?",urlMd5)
if err == sql.ErrNoRows{
err = nil
// 数据库中没有记录,重新生成一个新的短url
shortUrl,errRet := generateShortUrl(req,urlMd5)
if errRet != nil{
err = errRet
return
}
response.ShortUrl = shortUrl
return
}
if err != nil{
return
}
response.ShortUrl = short.ShortUrl
return
}
func generateShortUrl(req *models.Long2ShortRequest,hashcode string)(shortUrl string,err error){
result,err := Db.Exec("insert INTO short_url(origin_url,hash_code)VALUES (?,?)",req.OriginUrl,hashcode)
if err != nil{
return
}
// 0-9a-zA-Z 六十二进制
insertId,_:= result.LastInsertId()
shortUrl = transTo62(insertId)
_,err = Db.Exec("update short_url set short_url=? where id=?",shortUrl,insertId)
if err != nil{
fmt.Println(err)
return
}
return
}
// 将十进制转换为62进制 0-9a-zA-Z 六十二进制
func transTo62(id int64)string{
// 1 -- > 1
// 10-- > a
// 61-- > Z
charset := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
var shortUrl []byte
for{
var result byte
number := id % 62
result = charset[number]
var tmp []byte
tmp = append(tmp,result)
shortUrl = append(tmp,shortUrl...)
id = id / 62
if id == 0{
break
}
}
fmt.Println(string(shortUrl))
return string(shortUrl)
}
func Short2Long(req *models.Short2LongRequest) (response *models.Short2LongResponse, err error) {
response = &models.Short2LongResponse{}
var short ShortUrl
err = Db.Get(&short,"select id,short_url,origin_url,hash_code from short_url where short_url=?",req.ShortUrl)
if err == sql.ErrNoRows{
response.Code = 404
return
}
if err != nil{
response.Code = 500
return
}
response.OriginUrl = short.OriginUrl
return
}
func GetLastShortUrl(limit int)(result []*models.ShortUrl,err error){
err = Db.Select(&result,"select short_url from short_url ORDER BY id DESC limit ? ",limit)
return
}
在这里添加了一些之前没有的功能: 获取数据库所有的short url 并且显示在页面上了,不过这里非常丑,如图:
我们可以通过点击相应的连接就会跳转到长url的页面 也可以通过模拟发送post请求来查看转换的情况:
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SSM 单体框架 - 教育平台后台管理系统:视频讲解
- Day19.python时间和日期
- Kafka重要知识点之消费组概念
- Day15.异常的处理
- 「翻译」在生物信息学中使用 GNU-Parallel
- Kafka运维小贴士 | Kafka 消息监控
- MySQL慢查询优化 | 联结原理
- MySQL千万大表优化实践
- GitHub 标星过万!计算机与网络知识总结电子书下载!
- 盘一盘,那些提效/创意的 vscode 插件
- 基于jenkins实现手动拉取码云代码,实现半自动化部署
- so easy!网页骨架屏自动生成方案(dps)
- 深夜,我偷听到程序员要对session下手……
- CAM 系列论文阅读总结
- kafka客户端指标上报Prometheus方案(已开源)