通过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就是短网址 前段页面如下
随机推荐
- JPA实体的常用注解
@Entity 标注于实体类上,通常和@Table是结合使用的,代表是该类是实体类@Table 标注于实体类上,表示该类映射到数据库中的表,没有指定名称的话就表示与数据库中表名为该类的简单类名的表名相 ...
- java基础之继承(二)
上篇我们介绍了java中的构造方法,了解了关键字this和super在继承中所起到的作用,this可以显式调用重载的构造方法,super可以显式的调用父类中的任意可见方法.了解方法重载和重写的区别,知 ...
- SQL总结手册
1.SQL语法 (1)查询 SQL查询是使用最多的,需要凭借结构.索引和字段类型等因素.大多数据库含有一个优化器(optimizer),把用户查询转换为可选形式,以提高查询效率. 基本语法为: SEL ...
- Java中equal和==区别及String创建过程
Java中equal和==区别 1.起因 在一段Java代码中,使用了两种实现方式. //第一种命令行输入 int main (String[] args) { if(args[0] == " ...
- 常用的Java转义字符
1.常用的Java转义字符 \n : 回车 \t : 水平制表符 \r : 换行 \f : 换页 \' : 单引号 \'' : 双引号 ...
- R语言︱大数据集下运行内存管理
在实操时出现以下的问题: Error: cannot allocate vector of size 2.9GB 大神指导(http://bbs.pinggu.org/thread-3682816-1 ...
- Solution for link error:Cannot Open File 'python27_d.lib'
引自:http://guangboo.org/2013/01/17/solution-link-errorcannot-open-file-python27_dlib 感谢原作者 使用C调用Pytho ...
- servlet上传文件报错(三)
1.具体报错如下 null null Exception in thread "http-apr-8686-exec-5" java.lang.OutOfMemoryError: ...
- Parse Fatal Error at line 41 column 24: 元素类型 "url-pattern" 必须由匹配的结束标记 "</url-pattern>" 终止
1.错误描述 严重: Parse Fatal Error at line 41 column 24: 元素类型 "url-pattern" 必须由匹配的结束标记 "< ...
- 基于jQuery的一个提示功能的实现
最近有点忙,没有时间更新自己的博客,只能说我在原地踏步了,不知道你们进步了没有? 今天给大家分享一个提示的实现,有点简单,适合小白同学学习.下面是效果图 提示的功能: 当鼠标进入“我的菜单”的子菜单时 ...