golang与mongodb学习成果展示

golang与mongodb学习成果展示,第1张

golangmongodb学习成果展示 一,概述1别人2我 二,项目原理1短网址原理2本项目原理(1)原理概述(2)代码安全性 三,项目成果分享第一部分 点击跳转第二部分 数据库1结构体的定义2结构体的使用 第三部分 html模板与动作1文件结构2源码与说明3执行效果 第四部分 本地整合与测试1主函数外部(1)导入包说明(2)数据库连接(3)定义结构体(4)执行插入 2主函数内部(1)定义路由(2)加载并使用HTML模板(3)index.html(4)调用插入(5)所有定向跳转的查询、输出(6)查询并执行跳转(7)开启服务 3数据库说明4测试效果(1)路由测试index.htmlshow定向跳转 (2)shell测试结果 第五部分 搭建服务器环境并测试1 golang默认代理被墙2安装golang,mongodb3bulid运行(1)build 项目(2)写执行脚本 run.sh(3) run.sh运行 四,总结

一,概述 1别人

2我

从2021年11月29日的第一条有关mongodb的记录起,我一路浏览并详细学习了mongdb权威教程一、三,两版本,(三网上的资源白嫖不到,于是就自己出资购买了)golang的基础语法。

时至昨日,我基本学会了linux+golang+mongodb的网络服务。

这算是给自己的新年礼物了吧。
下面,将对个人立项“基于短网址原理的重定向”进行简要分享。

哦,对了,至于我为什么要学习mongodb和golang还特意接触gin框架和mgo.v2,在下一篇博客中,我会作出说明~~~~~

二,项目原理 1短网址原理

就是用一个随机码对应一个地址,然后在数据库里查找这个随机码,就可以找到对应的网址 。
当我们在浏览器里输入 http://url/RlB2PdD 时

(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本项目原理 (1)原理概述

本项目原理与短网址大致相同,下面概述一下不同之处:

增设html页面,人工输入api参数和重定向url,插入链接。
增设/show页面,展示数据库内已有文档。
删除随机码生成脚本,使用用户指定的api参数最为“短网址”。

(2)代码安全性

无任何安全措施,仅用于初学实现功能。

三,项目成果分享

备注:项目在制作的过程中每个部分是独立进行的,所以每个部分的具体内容会与最终的代码有细微的出入。

第一部分 点击跳转

这部分比较简单,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。
这里就介绍一下查询和插入的坑点,具体代码见第四部分。

1结构体的定义

注意结构体名称和对象要大写,血淋淋的教训。

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执行效果


第四部分 本地整合与测试 1主函数外部 (1)导入包说明

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:""}

4测试效果

由于本人觉得go语言免费IDE不大好用,于是就使用文本编辑器进行编程,以下截图若有命令执行,皆为shell执行。

(1)路由测试 index.html

show

定向跳转

访问http://192.168.159.129:8080/daydream
访问http://192.168.159.129:8080/daydreamblog

(2)shell测试结果

顺带提一下,shell这里有个小坑,如果浏览器没有及时清理缓存,shell是抓不到流量的。

第五部分 搭建服务器环境并测试 1 golang默认代理被墙


换一个国内能访问的代理地址:

https://goproxy.cn

执行命令:

go env -w GOPROXY=https://goproxy.cn

2安装golang,mongodb

二者配置过程就略了,初学的时候大家都会的。
下面展示一下在服务器上的运行结果:

3bulid运行 (1)build 项目

go build main.go
chmod 777 main

(2)写执行脚本 run.sh

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
以上就是项目的全部内容了,由于目的不在于立项,兴许项目比较简陋,但学习的成果已然明了,近三个月的付出总算没有白费。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/994489.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存