SpringBoot实现短链跳转

目录

1.背景介绍

2.短链跳转的意义    

3.SpringBoot中的代码实现

1.建议短链-长链的数据库表:t_url_map:

2.映射实体

3.Dao层实现

4.Service层实现

5.Controller层实现 

3.结果测试

4.问题


1.背景介绍

        短链跳转是一种通过将长链接转换为短链接的方式,以便在互联网上进行链接共享和传播的技术。通常情况下,长链接可能由于包含大量参数或者较长的路径而显得复杂且不易记忆,而短链则是将原始长链接通过特定算法转换为较短的链接,使得它更容易分享、传播和展示

        短链跳转服务通常由第三方提供,用户可以将需要缩短的长链接提交到该服务,服务会返回一个短链接,当用户访问这个短链接时,会被重定向到原始的长链接地址。这种服务通常还提供了统计功能,可以跟踪短链接被点击的次数访问来源等信息,帮助用户了解链接的传播效果。

        短链跳转服务有助于美化链接、节省空间、方便分享和统计链接访问情况,因此被广泛应用于社交媒体、微博客、推广活动等各种互联网应用场景中。

        比如在b站中,一个视频的网址原来是这样的:

        在移动端中,点击分享按钮,复制其链接:

       

        它会变成如下链接形式:

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

        点击该链接后,你会发现浏览器的网址URL为原来的长链接形式,也就是说这其中发生了重定向 ,而这个过程就是这篇博客要提到的短链跳转了。

2.短链跳转的意义    

  1. 节省空间:长链接可能会很长,不方便分享或展示,通过短链跳转可以将长链接转换为短链接,节省字符空间。

  2. 美化链接:短链看起来更简洁、美观,对于需要展示给用户或发布到社交媒体等场景更具吸引力。

  3. 防止链接失效:某些长链接可能会因为过期、失效或变动而无法访问,通过短链跳转可以在后台进行管理和更新,保证链接的可访问性。

  4. 统计和跟踪:通过短链跳转服务可以对链接的点击量、来源、地域等信息进行统计和分析,帮助用户了解链接的受众和效果。

  5. 方便分享:短链更容易复制、粘贴和分享,适用于短信、微博、邮件等分享场景,提高分享效率。

  6. 隐藏原始链接:有时候希望隐藏原始链接的信息,通过短链跳转可以起到一定的保护作用,防止泄露敏感信息。

3.SpringBoot中的代码实现

        这里我们以快速入门为主,即主要实现长链到短链的映射逻辑。

1.建议短链-长链的数据库表: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层实现

        这里简单写三个关键的接口方法:根据长链找短链(若无则生成短链)、根据短链找长链(若无则跳转失败页面)、插入实体

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);}

        对应的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_mapwhere 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_mapwhere shortUrl = #{shortUrl} limit 1</select>
4.Service层实现
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 {@Resourceprivate UrlMapMapper urlMapMapper;// 编码public String encode(String longUrl,String username) {UrlMap urlMap = urlMapMapper.findFirstByLongUrl(longUrl,username);// 看看该长链接是否存在// 如果存在并且其对应用户名等于已有用户名,则直接给出短链接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){// 根据短链接获取长链接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));// 将字节数组转换为十六进制字符串}return sb.toString().substring(0, 8)+username;// 截取前8位,加上用户名(这里先简单默认用户名是4位数)} catch (NoSuchAlgorithmException e) {e.printStackTrace();return null;}}}
5.Controller层实现 
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 {@Resourceprivate UrlMapService urlMapService;@PostMapping("/shorten")// 长链接转短连接,相当于实际项目中的点击“分享”,形成一条短连接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);}}

相关的ResponseBean的返回结果集代码:

public class ResponseBean<T> {/** 200:操作成功  -1:操作失败**/// http 状态码private boolean success;// 返回的数据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;}}

3.结果测试

        我们就拿刚刚那个b站的长链接作测试,即https://www.bilibili.com/video/BV18u4m1K7D4/?spm_id_from=333.1007.tianma.10-4-38.click&vd_source=1c7e32cfbc70017a24ee2c337620ff51

        

        可以看到短链接生成为1b9590bezhan,

        然后我们再用这条链接去测试能否跳转到原始链接:

        

        成功根据短链接定向到原始链接的网站了。

4.问题

        1.为什么生成短链接需要带上username参数?

         答:这里其实模仿的是不同用户对应同一个原始链接(或长链接)时,确保他们生成的短链接各不相同,这样可以方便后台追踪是由哪个用户分享的短链接,进而统计分享数。在表中LongUrl和shortUrl的对应关系为一对多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/712654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

南方电网的能源棋局上,蔚来换电扮演什么角色?

2 月 26 日&#xff0c;南网储能科技与蔚来能源签署协议&#xff0c;将充换电站、储能站、可调负载等聚合资源连接到虚拟电厂平台&#xff0c;推动换电站作为分布式储能在虚拟电厂项目上的应用。 蔚来换电站是国内首个智慧微电网型分布式换电设施&#xff0c;可透过换电订单预…

软考-系统集成项目管理中级-信息系统建设与设计

本章重点考点 1.信息系统的生命周期 信息系统建设的内容主要包括设备采购、系统集成、软件开发和运维服务等。信息系统的生命周期可以分为四个阶段:立项、开发、运维和消亡。 2.信息系统开发方法 信息系统常用的开发方法有结构化方法、原型法、面向对象方法等 1)结构化方法 …

AI智能分析网关V4:抽烟/打电话/玩手机行为AI算法及场景应用

抽烟、打电话、玩手机是人们在日常生活中常见的行为&#xff0c;但这些行为在某些场合下可能会带来安全风险。因此&#xff0c;对于这些行为的检测技术及应用就变得尤为重要。今天来给大家介绍一下TSINGSEE青犀AI智能分析网关V4抽烟/打电话/玩手机检测算法及其应用场景。 将监控…

java项目打包运行报异常:xxxxx-1.0-SNAPSHOT.jar中没有主清单属性

pom.xml中加入这段话即可 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.4</version><executions><execution><…

安泰ATA-7050高压放大器在微流控细胞分选中的应用

微流控细胞分选是一种用于分离和鉴定生物样本中特定类型细胞的技术&#xff0c;其原理基于将生物细胞通过微通道进行操纵和区分。微流控细胞分选的原理主要基于流体力学、电气学、光学和热力学等多学科的交叉应用。通过设计具有特定尺寸和性质的微通道网络&#xff0c;可实现对…

RV1126芯片概述

RV1126芯片概述 前言1 主要特性2 详细参数 前言 1 主要特性 四核 ARM Cortex-A7 and RISC-V MCU250ms快速开机2.0Tops NPU14M ISP with 3帧 HDR支持3个摄像头同时输入4K H.264/H.265 视频编码和解码 2 详细参数

永磁同步电机无感FOC(龙伯格观测器)算法技术总结-仿真篇

文章目录 1、观测器的引入2、β轴向下的电机观测器数学模型3、β轴向下的转子点角度及速度观测4、Simulink仿真模型搭建4.1模型总览4.2 Luenberger观测器模块4.2.1 I_alpha观测4.2.2 I_beta观测4.2.3 e_alpha、e_beta观测4.2.4 锁相环 4.3 速度设定4.4 速度观测结果4.5 电角度观…

express+mysql+vue,从零搭建一个商城管理系统6--数据校验和登录

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、修改models/user.js二、修改routes下的user.js三、Api新建user/login接口四、删除数据库原有数据&#xff0c;添加新验证规则的用户四、用户登录总结 前言 需求&#xff1a;主要学习express&#xff0c;…

MacBook将iPad和iPhone备份到移动硬盘

#创作灵感# 一个是ICloud不够用&#xff0c;想备份到本地&#xff1b;然而本地存储不够用&#xff0c;增加容量巨贵&#xff0c;舍不得这个钱&#xff0c;所以就想着能不能备份到移动硬盘。刚好有个移动固态&#xff0c;所以就试了一下&#xff0c;还真可以。 #正文# 说一下逻…

《PyTorch深度学习实践》第八讲加载数据集

一、 1、DataSet 是抽象类&#xff0c;不能实例化对象&#xff0c;主要是用于构造我们的数据集 2、DataLoader 需要获取DataSet提供的索引[i]和len;用来帮助我们加载数据&#xff0c;比如说做shuffle(提高数据集的随机性)&#xff0c;batch_size,能拿出Mini-Batch进行训练。它…

Windows10环境下MongoDB安装配置

1. 下载对应MongoDB安装包 进入官网&#xff1a;MongoDB官网 如果不连接外网则在官网下载较慢&#xff0c;这里给出下载好的安装包&#xff0c;版本为4.2.25&#xff1a;百度网盘 选择你需要的版本&#xff0c;推荐选择Package的格式为zip&#xff08;解压即可&#xff09; Pa…

[VNCTF2024]-PWN:preinit解析(逆向花指令,绕过strcmp,函数修改,机器码)

查看保护&#xff1a; 查看ida&#xff1a; 这边其实看反汇编没啥大作用&#xff0c;需要自己动调。 但是前面的绕过strcmp还是要看一下的。 解题&#xff1a; 这里是用linux自带的产生随机数的文件urandom来产生一个随机密码&#xff0c;然后让我们输入密码&#xff0c;用st…

k8s 存储卷详解与动静部署详解

目录 一、Volume 卷 1.1 卷类型 emptyDir &#xff1a; hostPath&#xff1a; persistentVolumeClaim (PVC)&#xff1a; configMap 和 secret&#xff1a; 二、 emptyDir存储卷 2.1 特点 2.2 用途&#xff1a; 2.3 示例 三、 hostPath存储卷 3.1 特点 3.2 用途 …

前端mock数据 —— 使用Apifox mock页面所需数据

前端mock数据 —— 使用Apifox 一、使用教程二、本地请求Apifox所mock的接口 一、使用教程 在首页进行新建项目&#xff1a; 新建项目名称&#xff1a; 新建接口&#xff1a; 创建json&#xff1a; 请求方法&#xff1a; GET。URL&#xff1a; api/basis。响应类型&#xff1…

Socket网络编程(六)——简易聊天室案例

目录 聊天室数据传输设计客户端、服务器数据交互数据传输协议服务器、多客户端模型客户端如何发送消息到另外一个客户端2个以上设备如何交互数据&#xff1f; 聊天室消息接收实现代码结构client客户端重构server服务端重构自身描述信息的构建重构TCPServer.java基于synchronize…

Nginx多次代理后获取真实的用户IP访问地址

需求&#xff1a;记录用户操作记录&#xff0c;类似如下表格的这样 PS: 注意无论你的服务是Http访问还是Https 访问的都是可以的&#xff0c;我们服务之前是客户只给开放了一个端口&#xff0c;但是既要支持https又要支持http协议&#xff0c;nginx 是可以通过stream 模块配置双…

2023中国PostgreSQL数据库生态大会:洞察前沿趋势,探索无限可能(附核心PPT资料下载)

随着数字化浪潮的推进&#xff0c;数据库技术已成为支撑各行各业数字化转型的核心力量。2023中国PostgreSQL数据库生态大会的召开&#xff0c;无疑为业界提供了一个深入交流、共同探索PostgreSQL数据库技术未来发展趋势的平台。本文将带您走进这场盛会&#xff0c;解析大会的亮…

k8s Pod基础(概念,容器功能及分类,镜像拉取和容器重启策略)

目录 pod概念 Kubernetes设计Pod概念和特殊组成结构的用意 Pod内部结构&#xff1a; 网络共享&#xff1a; 存储共享&#xff1a; pause容器主要功能 pod创建方式 pod使用方式 pod分类 pod的容器分类 基础容器&#xff08;infrastructure container&#xff09;&…

元宇宙3D虚拟场景制作深圳华锐视点免费试用

随着元宇宙兴起&#xff0c;3D线上展厅得到了越来越多的关注和应用。基于VR虚拟现实技术的元宇宙3D线上展厅在线编辑系统&#xff0c;更是为企业在展览展示领域带来了前所未有的辅助。 高效便捷&#xff1a; 元宇宙3D线上展厅在线编辑无需复杂的施工和搭建过程&#xff0c;只需…

报错问题解决django.db.utils.OperationalError: (1049, “Unknown database ‘ mxshop‘“)

开发环境&#xff1a;ubuntu22.04 pycharm 功能&#xff1a;django连接使用mysql数据库&#xff0c;各项配置看似正常 报错&#xff1a; django.db.utils.OperationalError: (1049, "Unknown database mxshop") 分析检查原因&#xff1a; Setting的配置文件内&…