一小時快速擼出一個短網址生成項目

寫在最前面

 項目完整源碼(歡迎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;
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章