最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot短鏈接跳轉(zhuǎn)的代碼實現(xiàn)

 更新時間:2024年03月01日 10:01:48   作者:蝸牛變渦流  
短鏈跳轉(zhuǎn)是一種通過將長鏈接轉(zhuǎn)換為短鏈接的方式,以便在互聯(lián)網(wǎng)上進行鏈接共享和傳播的技術(shù),短鏈將原始長鏈接通過特定算法轉(zhuǎn)換為較短的鏈接,使得它更容易分享、傳播和展示,本文給大家介紹了SpringBoot短鏈接跳轉(zhuǎn)的代碼實現(xiàn),需要的朋友可以參考下

1.背景介紹

短鏈跳轉(zhuǎn)是一種通過將長鏈接轉(zhuǎn)換為短鏈接的方式,以便在互聯(lián)網(wǎng)上進行鏈接共享和傳播的技術(shù)。通常情況下,長鏈接可能由于包含大量參數(shù)或者較長的路徑而顯得復(fù)雜且不易記憶,而短鏈則是將原始長鏈接通過特定算法轉(zhuǎn)換為較短的鏈接,使得它更容易分享、傳播和展示。

短鏈跳轉(zhuǎn)服務(wù)通常由第三方提供,用戶可以將需要縮短的長鏈接提交到該服務(wù),服務(wù)會返回一個短鏈接,當(dāng)用戶訪問這個短鏈接時,會被重定向到原始的長鏈接地址。這種服務(wù)通常還提供了統(tǒng)計功能,可以跟蹤短鏈接被點擊的次數(shù)、訪問來源等信息,幫助用戶了解鏈接的傳播效果。

短鏈跳轉(zhuǎn)服務(wù)有助于美化鏈接、節(jié)省空間、方便分享和統(tǒng)計鏈接訪問情況,因此被廣泛應(yīng)用于社交媒體、微博客、推廣活動等各種互聯(lián)網(wǎng)應(yīng)用場景中。

比如在b站中,一個視頻的網(wǎng)址原來是這樣的:

在移動端中,點擊分享按鈕,復(fù)制其鏈接:      

它會變成如下鏈接形式:

【Cookie、Session、Token、JWT一次性講完-嗶哩嗶哩】 https://b23.tv/0SMtYq6

點擊該鏈接后,你會發(fā)現(xiàn)瀏覽器的網(wǎng)址URL為原來的長鏈接形式,也就是說這其中發(fā)生了重定向 ,而這個過程就是這篇博客要提到的短鏈跳轉(zhuǎn)了。

2.短鏈跳轉(zhuǎn)的意義 

  • 節(jié)省空間:長鏈接可能會很長,不方便分享或展示,通過短鏈跳轉(zhuǎn)可以將長鏈接轉(zhuǎn)換為短鏈接,節(jié)省字符空間。
  • 美化鏈接:短鏈看起來更簡潔、美觀,對于需要展示給用戶或發(fā)布到社交媒體等場景更具吸引力。
  • 防止鏈接失效:某些長鏈接可能會因為過期、失效或變動而無法訪問,通過短鏈跳轉(zhuǎn)可以在后臺進行管理和更新,保證鏈接的可訪問性。
  • 統(tǒng)計和跟蹤:通過短鏈跳轉(zhuǎn)服務(wù)可以對鏈接的點擊量、來源、地域等信息進行統(tǒng)計和分析,幫助用戶了解鏈接的受眾和效果。
  • 方便分享:短鏈更容易復(fù)制、粘貼和分享,適用于短信、微博、郵件等分享場景,提高分享效率。
  • 隱藏原始鏈接:有時候希望隱藏原始鏈接的信息,通過短鏈跳轉(zhuǎn)可以起到一定的保護作用,防止泄露敏感信息。

3.SpringBoot中的代碼實現(xiàn)

這里我們以快速入門為主,即主要實現(xiàn)長鏈到短鏈的映射邏輯。

1.建議短鏈-長鏈的數(shù)據(jù)庫表:t_url_map:

2.映射實體

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.time.Instant;
 
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UrlMap {
 
 
    private Long id;
 
    private String longUrl;
 
    private String shortUrl;
 
    private String username;
 
    private Instant expireTime;
 
    private Instant creationTime;
 
 
 
}

這里要添加lombok依賴:

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

3.Dao層實現(xiàn)

這里簡單寫三個關(guān)鍵的接口方法:根據(jù)長鏈找短鏈(若無則生成短鏈)、根據(jù)短鏈找長鏈(若無則跳轉(zhuǎn)失敗頁面)、插入實體

import com.zhan.zhan215.Entity.UrlMap;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
 
import java.time.Instant;
import java.util.List;
 
 
@Mapper
public interface UrlMapMapper {
 
    UrlMap findFirstByLongUrl(@Param("longUrl") String longUrl, @Param("username") String username);
 
    void saveUrlMap(UrlMap urlMap);
 
    UrlMap findByShortUrl(String shortUrl);
 
 
}

對應(yīng)的xml映射:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhan.zhan215.Dao.UrlMapMapper">
 
    <select id="findFirstByLongUrl" parameterType="string" resultType="com.zhan.zhan215.Entity.UrlMap">
 
        select *
 
        from t_url_map
 
        where longUrl =#{longUrl} and username = #{username}
 
        limit 1
 
    </select>
 
    <!-- 在Mapper XML文件中定義保存urlMap對象的方法 -->
    <insert id="saveUrlMap" parameterType="com.zhan.zhan215.Entity.UrlMap">
        INSERT INTO t_url_map (shortUrl, longUrl,username)
        VALUES (#{shortUrl}, #{longUrl},#{username})
    </insert>
 
    <select id="findByShortUrl"  parameterType="string" resultType="com.zhan.zhan215.Entity.UrlMap">
 
        select *
 
        from t_url_map
 
        where shortUrl = #{shortUrl} limit 1
 
    </select>

4.Service層實現(xiàn)

import com.zhan.zhan215.Dao.UrlMapMapper;
import com.zhan.zhan215.Entity.UrlMap;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
 
@Service
public class UrlMapService {
 
    @Resource
    private UrlMapMapper urlMapMapper;
 
 
    // 編碼
    public String encode(String longUrl,String username) {
 
        UrlMap urlMap = urlMapMapper.findFirstByLongUrl(longUrl,username);
 
        // 看看該長鏈接是否存在
        // 如果存在并且其對應(yīng)用戶名等于已有用戶名,則直接給出短鏈接
        if (urlMap != null&&username.equals(urlMap.getUsername())) {
            return urlMap.getShortUrl();
 
        } else {
            // 如果不存在,則生成短鏈接
            UrlMap urlMap1 = new UrlMap();
            // 生成短鏈接
            String shortLink = generateShortLink(longUrl,username);
            // 保存短鏈接
            urlMap1.setLongUrl(longUrl);
            urlMap1.setShortUrl(shortLink);
            urlMap1.setUsername(username);
            urlMap1.setCreationTime(Instant.now());
            urlMapMapper.saveUrlMap(urlMap1);
 
 
            return shortLink;
        }
    }
 
    // 解碼
    public String decode(String shortUrl){
 
        // 根據(jù)短鏈接獲取長鏈接
        UrlMap byShortUrl = urlMapMapper.findByShortUrl(shortUrl);
 
        // 如果存在,返回長鏈接
        if(byShortUrl!=null){
            return byShortUrl.getLongUrl();
        }
 
        // 如果沒有,返回首頁(正常是返回一個失敗頁面)
        return "https://bilibili.com";
 
    }
 
    // 生成短鏈接
    public static String generateShortLink(String originalUrl,String username) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(originalUrl.getBytes());
            // 對原始URL進行MD5哈希計算
 
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b));
                // 將字節(jié)數(shù)組轉(zhuǎn)換為十六進制字符串
            }
 
            return sb.toString().substring(0, 8)+username;
            // 截取前8位,加上用戶名(這里先簡單默認用戶名是4位數(shù))
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
 
 
}

5.Controller層實現(xiàn) 

import com.zhan.zhan215.Common.ResponseBean;
import com.zhan.zhan215.Service.UrlMapService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;
 
import javax.annotation.Resource;
 
@RestController
public class UrlMapController {
 
    @Resource
    private UrlMapService urlMapService;
 
 
 
    @PostMapping("/shorten")
    // 長鏈接轉(zhuǎn)短連接,相當(dāng)于實際項目中的點擊“分享”,形成一條短連接
    public ResponseBean shorten(@RequestParam String longUrl,@RequestParam String username){
 
        String encode =  urlMapService.encode(longUrl,username);
        // 形成短鏈
 
        return ResponseBean.success(encode);
 
    }
 
    @GetMapping("redirect")
    //重定向
    public RedirectView redirectView(@RequestParam String shortUrl){
 
        String longUrl = urlMapService.decode(shortUrl);
 
        return new RedirectView(longUrl);
    }
 
}

相關(guān)的ResponseBean的返回結(jié)果集代碼:

public class ResponseBean<T> {
 
    /** 200:操作成功  -1:操作失敗**/
 
    // http 狀態(tài)碼
    private boolean success;
 
    // 返回的數(shù)據(jù)
    private T data;
 
    public boolean isSuccess() {
        return success;
    }
 
    public void setSuccess(boolean success) {
        this.success = success;
    }
 
    public T getData() {
        return data;
    }
 
    public void setData(T data) {
        this.data = data;
    }
 
    public static <T> ResponseBean<T> success(T data) {
        ResponseBean<T> responseBean = new ResponseBean<>();
        responseBean.setSuccess(true);
        responseBean.setData(data);
        return responseBean;
    }
 
    public static <T> ResponseBean<T> error(T errorData) {
        ResponseBean<T> responseBean = new ResponseBean<>();
        responseBean.setSuccess(false);
        responseBean.setData(errorData);
        return responseBean;
    }
 
    public static <T> ResponseBean<T> success() {
        ResponseBean<T> responseBean = new ResponseBean<>();
        responseBean.setSuccess(true);
        return responseBean;
    }
 
}

4.結(jié)果測試

我們就拿剛剛那個b站的長鏈接作測試,即https://www.bilibili.com/video/BV18u4m1K7D4/?spm_id_from=333.1007.tianma.10-4-38.click&vd_source=1c7e32cfbc70017a24ee2c337620ff51    

可以看到短鏈接生成為1b9590bezhan,

然后我們再用這條鏈接去測試能否跳轉(zhuǎn)到原始鏈接:     

成功根據(jù)短鏈接定向到原始鏈接的網(wǎng)站了。

5.問題

1.為什么生成短鏈接需要帶上username參數(shù)?

答:這里其實模仿的是不同用戶對應(yīng)同一個原始鏈接(或長鏈接)時,確保他們生成的短鏈接各不相同,這樣可以方便后臺追蹤是由哪個用戶分享的短鏈接,進而統(tǒng)計分享數(shù)。在表中LongUrl和shortUrl的對應(yīng)關(guān)系為一對多

以上就是SpringBoot短鏈接跳轉(zhuǎn)的代碼實現(xiàn)的詳細內(nèi)容,更多關(guān)于SpringBoot短鏈接跳轉(zhuǎn)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java 時間轉(zhuǎn)換的實例代碼

    Java 時間轉(zhuǎn)換的實例代碼

    下面小編就為大家?guī)硪黄狫ava 時間轉(zhuǎn)換的實例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • java中springMVC獲取請求參數(shù)的方法

    java中springMVC獲取請求參數(shù)的方法

    這篇文章主要介紹了java中springMVC獲取請求參數(shù)的方法,springmvc是spring框架的一個模塊,springmvc和spring無需通過中間整合層進行整合,需要的朋友可以參考下
    2023-05-05
  • RocketMQ發(fā)送事務(wù)消息詳解

    RocketMQ發(fā)送事務(wù)消息詳解

    這篇文章主要介紹了RocketMQ發(fā)送事務(wù)消息詳解,RocketMQ分布式事務(wù)消息不僅可以實現(xiàn)應(yīng)用之間的解耦,又能保證數(shù)據(jù)的最終一致性,傳統(tǒng)的大事務(wù)可以被拆分為小事務(wù),不僅能提升效率,還不會因為某一個關(guān)聯(lián)應(yīng)用的不可用導(dǎo)致整體回滾,需要的朋友可以參考下
    2023-09-09
  • OpenCV Java實現(xiàn)人臉識別和裁剪功能

    OpenCV Java實現(xiàn)人臉識別和裁剪功能

    這篇文章主要為大家詳細介紹了OpenCV Java實現(xiàn)人臉識別和裁剪功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • MyBatis if choose 動態(tài) SQL的實現(xiàn)

    MyBatis if choose 動態(tài) SQL的實現(xiàn)

    本文主要介紹了MyBatis if choose 動態(tài) SQL的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-05-05
  • 淺談Spring中@NotEmpty、@NotBlank、@NotNull區(qū)別

    淺談Spring中@NotEmpty、@NotBlank、@NotNull區(qū)別

    本文主要介紹了淺談Spring中@NotEmpty、@NotBlank、@NotNull區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Spring中的Aware接口詳細解析

    Spring中的Aware接口詳細解析

    這篇文章主要介紹了Spring中的Aware接口詳細解析,Aware是一個具有標(biāo)識作用的超級接口,具體實現(xiàn)是有子接口去決定的,但是子接口至少要有一個帶一個參數(shù)的且返回是空的方法,需要的朋友可以參考下
    2023-12-12
  • SpringBoot基于Minio實現(xiàn)分片上傳、斷點續(xù)傳的實現(xiàn)

    SpringBoot基于Minio實現(xiàn)分片上傳、斷點續(xù)傳的實現(xiàn)

    本文主要介紹了SpringBoot基于Minio實現(xiàn)分片上傳、斷點續(xù)傳的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • Java的封裝類和裝箱拆箱詳解

    Java的封裝類和裝箱拆箱詳解

    Java中存在基礎(chǔ)數(shù)據(jù)類型,但是在某些情況下,我們要對基礎(chǔ)數(shù)據(jù)類型進行對象的操作,例如,集合中只能存對象,而不能存在基礎(chǔ)數(shù)據(jù)類型,于是便出現(xiàn)了封裝類,本文將詳細給大家介紹Java封裝類和裝箱拆箱,需要的朋友可以參考下
    2023-05-05
  • spring boot項目生成docker鏡像并完成容器部署的方法步驟

    spring boot項目生成docker鏡像并完成容器部署的方法步驟

    這篇文章主要介紹了spring boot項目生成docker鏡像并完成容器部署的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10

最新評論

桃源县| 凭祥市| 天柱县| 龙岩市| 湘阴县| 七台河市| 柳林县| 华阴市| 隆安县| 临沂市| 屏东市| 青川县| 明星| 清远市| 龙井市| 两当县| 红安县| 曲水县| 邢台市| 临泉县| 文山县| 焉耆| 荣昌县| 彰化县| 麻城市| 蒲江县| 江孜县| 吴堡县| 杭州市| 秭归县| 博乐市| 临漳县| 综艺| 怀来县| 灵寿县| 奈曼旗| 房山区| 祁门县| 广东省| 金昌市| 仪陇县|