通过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请求来查看转换的情况:


通过Beego将之前实现的短url项目实现的更多相关文章
- Go实现短url项目
首先说一下这种业务的应用场景: 把一个长url转换为一个短url网址 主要用于微博,二维码,等有字数限制的场景 主要实现的功能分析: 把长url的地址转换为短url地址 通过短url获取对应的原始长u ...
- Go 实现短 url 项目
首先说一下这种业务的应用场景: 把一个长 url 转换为一个短 url 网址 主要用于微博,二维码,等有字数限制的场景 主要实现的功能分析: 把长 url 地址转换为短 url 地址 通过短 url ...
- SharePoint 2010 Url Shortener --SharePoint 2010 短URL生成器
SharePoint 2010 Url Shortener --SharePoint 2010 短URL生成器 项目描写叙述 本项目加入了这种功能.在SP站点中能够生成短URLs. 这些URLs指向列 ...
- 短URL
短网址应用已经在全国各大微博上开始流行了起来.例如QQ微博的url.cn,新郎的sinaurl.cn等. 我们在QQ微博上发布网址的时候,微博会自动判别网址,并将其转换,例如:http://url.c ...
- 二维码及二维码接合短URL的应用
二维码 1.什么是二维码? 二维条形码,最早发明于日本,它是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的,在代码编制上巧妙地利用构成计算机内部逻辑基础的“0 ...
- 短URL生成
算法原理 算法一 1)将长网址md5生成32位签名串,分为4段, 每段8个字节; 2)对这四段循环处理, 取8个字节, 将他看成16进制串与0x3fffffff(30位1)与操作, 即超过30位的忽略 ...
- django简单实现短url
一.短url的原理 什么是短url: 简单讲就是把普通正常访问的网址,转换成比较短的网址,例如:https://www.cnblogs.com/angelyan/articles/10667354.h ...
- 短URL系统、301/302重定向
短 URL 系统是怎么设计的?https://yq.aliyun.com/articles/87600 短网址(short URL)系统的原理及其实现 https://hufangyun.com/20 ...
- mongodb:短网址项目
短网址项目概述 1.短网址项目,是将给定的长网址,转换成短网址. 如 新浪 http://t.cn/zQd5NPw ,其中zQd5NPw就是短网址 前段页面如下
随机推荐
- java网络编程(7)——利用tcp实现文件上传
其实客户端与服务端通讯的道理都是一样的,都是通过输入与输出这两个流,那么实现文件上传也就是同样的,客户端把文件读到文件流,服务端用文件流来接受,然后写到一个文件中,这样子就实现了文件上传,文件拷贝也是 ...
- MyCat 读写分离,负载均衡
docker mysql 主从复制 配合Spring 事务 注意事项 配置好JRE,安装好MYCAT 在mysql主库创建表,会同步到从库 CREATE TABLE `user` ( `id` ) N ...
- Mybatis认识
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis .iB ...
- react 父子组件互相通信
1,父组件向子组件传递 在引用子组件的时候传递,相当于一个属性,例如: class Parent extends Component{ state = { msg: 'start' }; render ...
- <CEPH中国-深圳站-技术交流会演讲PPT> YY云平台Ceph Block应用实践 & 我写的书 《CEPH实战》
YY云平台Ceph Block应用实践 http://s3.yyclouds.com/public/YY%E4%BA%91%E5%B9%B3%E5%8F%B0Ceph%E5%AE%9E%E8%B7%B ...
- HighCharts之2D堆面积图
HighCharts之2D堆面积图 1.HighCharts之2D堆面积图源码 StackedArea.html: <!DOCTYPE html> <html> <hea ...
- HI3531由DMA 发起PCIe 事务
Hi3531 PCIe 控制器内含DMA 控制器,DMA 控制器包含有两个DMA 通道(一个 DMA 读通道和一个DMA 写通道).PCIe 控制器内包含的DMA 控制器用于大数据量 的存储器读写事务 ...
- RAPIDIO高速串行协议
RapidIO是由Motorola和Mercury等公司率先倡导的一种高性能. 低引脚数. 基于数据包交换的互连体系结构,是为满足和未来高性能嵌入式系统需求而设计的一种开放式互连技术标准.RapidI ...
- class-朴素贝叶斯NaiveBayes
1 朴素贝叶斯法的学习与分类1.1 基本原理2 参数估计2.1 极大似然估计2.2 算法2.3 贝叶斯估计 1 朴素贝叶斯法的学习与分类 Naive Bayes是基于贝叶斯定理和特征条件独立的假设的分 ...
- 【CF235C】Cyclical Quest(后缀自动机)
[CF235C]Cyclical Quest(后缀自动机) 题面 洛谷 题解 大致翻译: 给定一个串 然后若干组询问 每次也给定一个串 这个串可以旋转(就是把最后一位丢到最前面这样子) 问这个串以及其 ...