一小时快速撸出一个短网址生成项目

写在最前面

 项目完整源码(欢迎star):github项目源码
 项目临时预览地址(指不定什么时候就挂了):短网址生成项目预览

引入主题

 前几天在某论坛看到这样一篇帖子,说的是“大家第一个项目,都是从网址导航开始?”,浏览半天回复的内容发现都是大佬啊,有做了个浏览器插件的,有做了个博客的,这个—>“片段”<—更不错,手撸出来的多厉害。当然也有不少做的网址导航的,于是我想了想之前搞的一个项目,默默的评论了一句。
my
 翻到上面看到一位老哥说的是短网址项目。
短网址
 于是我脑瓜一热,百度了下短网址的原理。发现还是很简单的,说时迟那时快,我已经打开了IDEA,创建项目手撸开干。项目架构选择了springboot,持久层还是用的mybatis,前端依然是bootstrap。
用了不到一个下午的时间项目已经出来了。整个项目中,最浪费时间的还是前端调样式。前端菜的一批。
短网址

实现原理

下面说下实现的原理
 首先在用户输入一条长链接传到后端的时候,我先生成了数字和字母随机组成的6位字符,然后把这个字符和长链接保存到数据库。保存成功后,把这6位字符拼上我的网址,返回给用户,就像是这样的 https://wjup.top/HtN3Gc
 当用户拿到这个短网址访问的时候。我在后台进行获取这个短网址的6个字符,然后根据这个字符到数据库查询原来的链接,再进行301永久重定向到原网址就可以了。整体实现非常简单。当然我还增加了对短网址加密的功能,只有输入正确的密码才能访问原始链接

逻辑代码

下面放出主要的实现代码。项目完整版可以到github中去克隆岛到本地研究

package com.wjup.shorturl.controller;

import com.alibaba.fastjson.JSONObject;
import com.wjup.shorturl.entity.UrlEntity;
import com.wjup.shorturl.service.UrlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.util.DateUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
import java.util.UUID;

/**
 * Create by wjup on 2019/9/29 11:33
 * <p>
 * 短网址生成项目
 */

@Controller
public class UrlController {

    @Autowired
    private UrlService urlService;

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    /**
     * 创建短链接
     *
     * @param longUrl 原地址
     * @param viewPwd 访问密码
     * @param request 请求
     * @return json
     */
    @RequestMapping("/create")
    @ResponseBody
    public String creatShortUrl(String longUrl, String viewPwd, HttpServletRequest request) {
        JSONObject json = new JSONObject();
        String[] split = longUrl.split("\n|\r");
        StringBuffer msg = new StringBuffer();

        for (int i = 0; i < split.length; i++) {
            UrlEntity urlEntity = new UrlEntity();

            if (!split[i].contains("https://") && !split[i].contains("http://")) {
                split[i] = "http://" + split[i];
            }

            String shortUrlId = getStringRandom(6);
            urlEntity.setShortUrlId(shortUrlId);
            urlEntity.setUuid(UUID.randomUUID().toString());
            urlEntity.setLongUrl(split[i]);
            urlEntity.setCreateTime(DateUtils.format(new Date(), "yyyy-MM-dd HH-mm-ss", Locale.SIMPLIFIED_CHINESE));
            urlEntity.setViewPwd(viewPwd);

            int flag = urlService.createShortUrl(urlEntity);

            String toUrl = "/";
            int serverPort = request.getServerPort();
            if (serverPort == 80 || serverPort == 443) {
                toUrl = request.getScheme() + "://" + request.getServerName();
            } else {
                toUrl = request.getScheme() + "://" + request.getServerName() + ":" + serverPort;
            }

            if (flag > 0) {
                msg.append(toUrl + "/" + shortUrlId + "<br>");
            }
        }

        json.put("shortUrl", msg);
        return json.toJSONString();
    }

    /**
     * 访问短链接
     *
     * @param shortUrlId 短网址id
     * @param response   响应
     * @param request    请求
     * @throws ServletException 异常捕获
     * @throws IOException      异常捕获
     */
    @RequestMapping(value = "/{shortUrlId}")
    public void view(@PathVariable("shortUrlId") String shortUrlId, HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException {

        UrlEntity urlEntity = urlService.findByShortUrlId(shortUrlId);
        if (urlEntity != null) {
            if (urlEntity.getViewPwd() != null && !"".equals(urlEntity.getViewPwd())) {
                request.setAttribute("shortUrlId", shortUrlId);
                request.getRequestDispatcher("/viewPwd").forward(request, response);
            } else {
                urlService.updateShortUrl(shortUrlId);
                response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
                response.setHeader("Location", urlEntity.getLongUrl());
            }
        } else {
            request.getRequestDispatcher("/noPage").forward(request, response);
        }
    }

    /**
     * 没有该请求跳转到指定页面
     *
     * @return page
     */
    @RequestMapping("/noPage")
    public String noPage() {

        return "noPage";
    }

    /**
     * 有密码打开输入密码页面
     *
     * @return html
     */
    @RequestMapping("/viewPwd")
    public String viewPwd(HttpServletRequest request, Model model) {
        String shortUrlId = request.getAttribute("shortUrlId").toString();
        model.addAttribute("shortUrlId", shortUrlId);
        return "viewPwd";
    }

    /**
     * 验证密码是否正确
     *
     * @param viewPwd    密码
     * @param shortUrlId 短址id
     */
    @RequestMapping("/VerifyPwd")
    @ResponseBody
    public String VerifyPwd(String viewPwd, String shortUrlId) {
        UrlEntity urlEntity = urlService.findByPwd(viewPwd, shortUrlId);

        JSONObject jsonObject = new JSONObject();
        if (urlEntity != null) {
            urlService.updateShortUrl(shortUrlId);
            jsonObject.put("longUrl", urlEntity.getLongUrl());
            jsonObject.put("flag", true);
        } else {
            jsonObject.put("flag", false);
        }
        return jsonObject.toJSONString();
    }


    /**
     * 生成随机数字和字母
     *
     * @param length 生成长度
     * @return shortUrlId
     */
    private String getStringRandom(int length) {

        String val = "";
        Random random = new Random();

        //参数length,表示生成几位随机数
        for (int i = 0; i < length; i++) {

            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            //输出字母还是数字
            if ("char".equalsIgnoreCase(charOrNum)) {
                //输出是大写字母还是小写字母
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (random.nextInt(26) + temp);
            } else if ("num".equalsIgnoreCase(charOrNum)) {
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值