从2021年11月29日的第一条有关mongodb的记录起,我一路浏览并详细学习了mongdb权威教程一、三,两版本,(三网上的资源白嫖不到,于是就自己出资购买了)golang的基础语法。
时至昨日,我基本学会了linux+golang+mongodb的网络服务。
这算是给自己的新年礼物了吧。
下面,将对个人立项“基于短网址原理的重定向”进行简要分享。
二,项目原理 1短网址原理哦,对了,至于我为什么要学习mongodb和golang还特意接触gin框架和mgo.v2,在下一篇博客中,我会作出说明~~~~~
就是用一个随机码对应一个地址,然后在数据库里查找这个随机码,就可以找到对应的网址 。
当我们在浏览器里输入 http://url/RlB2PdD 时
2本项目原理 (1)原理概述(1)DNS首先解析获得 http://url 的 IP 地址
(2)当 DNS 获得 IP地址以后(比如:74.125.225.72),会向这个地址发送 HTTP GET 请求,查询短码 RlB2PdD
(3)http://url服务器会通过短码 RlB2PdD 获取对应的长 URL
(4)请求通过 HTTP 301 转到对应的长 URL https://www.baidu.com
本项目原理与短网址大致相同,下面概述一下不同之处:
(2)代码安全性增设html页面,人工输入api参数和重定向url,插入链接。
增设/show页面,展示数据库内已有文档。
删除随机码生成脚本,使用用户指定的api参数最为“短网址”。
无任何安全措施,仅用于初学实现功能。
三,项目成果分享备注:项目在制作的过程中每个部分是独立进行的,所以每个部分的具体内容会与最终的代码有细微的出入。
第一部分 点击跳转这部分比较简单,c.Redirect就可以解决:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/:name", func(c *gin.Context) {
name := c.Param("name")
c.String(http.StatusOK, name)//输出获取name的值
if name=="redirect"{ //通过变量来实现参数传递
c.Redirect(http.StatusMovedPermanently,"http://www.baidu.com")}
})
r.Run(":8080")
}
第二部分 数据库
go语言有各色针对mongodb的驱动,我这里选择的是mgo.v2。
这里就介绍一下查询和插入的坑点,具体代码见第四部分。
注意结构体名称和对象要大写,血淋淋的教训。
type Surl struct {
Urlname string `bson:"urlname"`
Nexturl string `bson:"nexturl"`
}
2结构体的使用
查询时,可以定义如下:
//ALL: var result []Surl 或者 result := []Surl{}
//One: result := Surl{}
插入时,可以定义如下:
//多条数据: reurl := []Surl{Surl{},Surl{}......}
//一条数据: reurl := Surl{......}
第三部分 html模板与动作
1文件结构
2源码与说明
index.html
这里应该不用多说,一看就懂。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>golang and mongodb实验title>
head>
<body>
<form action="http://192.168.159.129:8080/storage" method="post" action="application/x-www-form-urlencoded">
网址API:<input type="text" name="API" placeholder="请输入API"> <br>
重定向URL:<input type="text" name="URL" placeholder="请输入URL"> <br>
<input type="submit" value="提交">
form>
body>
html>
main.go
使用HTML模板访问index.html文件。(当然,不新建文件夹也可以,把下方的“/html”删掉即可,本人还进行了其他html测试,未来分类故创建html。)
使用”/storage“作为API参数,执行获取动作,通过POST表单传递参数。
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.LoadHTMLGlob("./html/*")
r.Handle("GET", "/", func(context *gin.Context) {
// 返回HTML文件,响应状态码200,html文件名为index.html,模板参数为nil
context.HTML(http.StatusOK, "index.html", nil)
})
r.POST("/storage", func(c *gin.Context) {
types := c.DefaultPostForm("type", "post")
api := c.PostForm("API")
url := c.PostForm("URL")
c.String(http.StatusOK, fmt.Sprintf("api:%s,url:%s,type:%s", api, url, types))//输出测试
})
r.Run()
}
3执行效果
fmt用于分段输出调试
os,mgo.v2,bson三个包为mongodb得连接与调用。
gin框架用于web测试
package main
import (
"fmt"
"net/http"
"os"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"github.com/gin-gonic/gin"
)
(2)数据库连接
以下代码的具体说明见注释
func InitMongoSession() *mgo.Session {
mHost := "127.0.0.1"
mPort := "27017"
mUsername := "root" //mongodb的账号
mPassword := "123456" //mongodb的密码
session, err := mgo.Dial(mHost + ":" + mPort)
if err != nil {
fmt.Println("mgo.Dial-error:", err)
os.Exit(0)
}
session.SetMode(mgo.Eventual, true)
myDB := session.DB("admin") //这里的关键是连接mongodb后,选择admin数据库,然后登录,确保账号密码无误之后,该连接就一直能用了
err = myDB.Login(mUsername, mPassword)
if err != nil {
fmt.Println("Login-error:", err)
os.Exit(0)
}
session.SetPoolLimit(10)
return session
}
(3)定义结构体
用来进行查询和插入
type Surl struct {
Urlname string `bson:"urlname"`
Nexturl string `bson:"nexturl"`
}
(4)执行插入
定义一个简单的插入函数
func insert(u,n string) string{
notice := "daydream is inserting......"
session := InitMongoSession()
myDB := session.DB("admin").C("s_url")
reurl := Surl{Urlname:u,Nexturl:n}
err := myDB.Insert(reurl)
if err != nil { panic(err) }
return notice
}
2主函数内部
(1)定义路由
r := gin.Default()
(2)加载并使用HTML模板
通过html模板加载index.html
r.LoadHTMLGlob("./html/*")// 指明html加载文件目录
r.Handle("GET", "/", func(context *gin.Context) { // 返回HTML文件,响应状态码200,html文件名为index.html,模板参数为nil
context.HTML(http.StatusOK, "index.html", nil)
})
(3)index.html
文件结构已在之前的部分叙述,这里就不在多说了。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>golang and mongodb实验title>
head>
<body>
<form action="http://192.168.159.129:8080/insert" method="post" action="application/x-www-form-urlencoded">
网址API:<input type="text" name="API" placeholder="请输入API"> <br>
重定向URL:<input type="text" name="URL" placeholder="请输入URL"> <br>
<input type="submit" value="提交">
form>
body>
html>
(4)调用插入
调用insert函数,从index.html表单获取参数并插入。
r.POST("/insert", func(c *gin.Context) {
//types := c.DefaultPostForm("type", "post")
api := c.PostForm("API")
url := c.PostForm("URL")
//c.String(http.StatusOK, fmt.Sprintf("api:%s,url:%s,type:%s", api, url, types))
c.String(http.StatusOK,insert(api,url))
})
(5)所有定向跳转的查询、输出
查询数据库内保存的定向跳转并输出。
r.GET("/show", func(c *gin.Context) {
session := InitMongoSession()
myDB := session.DB("admin").C("s_url")
var result []Surl
myDB.Find(bson.M{}).All(&result)
///*
for id,res :=range result{
//fmt.Println(res)
U := res.Urlname
N := res.Nexturl
c.String(http.StatusOK, fmt.Sprintf("id:%d,U:%s,N:%s\n",id,U,N))
}
//*/
})
(6)查询并执行跳转
获取api参数,通过在数据库内查询api参数,得到对应跳转连接。
r.GET("/:name", func(c *gin.Context) {
name := c.Param("name")//获取跳转api
session := InitMongoSession()
myDB := session.DB("admin").C("s_url")
result := Surl{}
err := myDB.Find(bson.M{"urlname": name}).One(&result)
if err != nil { panic(err) }
n := result.Nexturl
//c.String(http.StatusOK, name)//输出获取name的值
//n="http://www.baidu.com"
c.Redirect(http.StatusMovedPermanently,n) //通过变量来实现参数传递重定向
})
(7)开启服务
r.Run()
3数据库说明
s_url集合中共两个文档,如下图
文档格式:{urlname:"",nexturl:""}
由于本人觉得go语言免费IDE不大好用,于是就使用文本编辑器进行编程,以下截图若有命令执行,皆为shell执行。
(1)路由测试 index.html show 定向跳转访问http://192.168.159.129:8080/daydream
访问http://192.168.159.129:8080/daydreamblog
顺带提一下,shell这里有个小坑,如果浏览器没有及时清理缓存,shell是抓不到流量的。
换一个国内能访问的代理地址:
https://goproxy.cn
执行命令:
2安装golang,mongodbgo env -w GOPROXY=https://goproxy.cn
二者配置过程就略了,初学的时候大家都会的。
下面展示一下在服务器上的运行结果:
(2)写执行脚本 run.shgo build main.go
chmod 777 main
run.sh内容
#!/bin/bash
# 设置为 release 生产模式
export GIN_MODE=release
# 切换到路径下,这样才能够使用和开发时候一样的相对路径
cd /home/go/src/short_url
# 启动 build 后的可执行文件
./main
(3) run.sh运行
四,总结./run.sh
源代码就放到github上了,CSDN审核太慢了。
这周末在做梦的github
以上就是项目的全部内容了,由于目的不在于立项,兴许项目比较简陋,但学习的成果已然明了,近三个月的付出总算没有白费。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)