短链,通俗地讲就是将原本非常长的URL链接精简,让短链接也能访问到原本的长链接。比如给我们发送的系统通知。长链和短链让我们都能访问到同一篇文章。
原理还是简单的,当用户访问短链时,我们给他返回302的状态,在header中带上Location,告诉浏览器这是一个临时文件,真正的文件需要访问Location中的地址。
那么长链又是转成短链的呢?后端接收到前端传过来的长链后,首先用hash算法将长链转成10进制的一组数,用md5或者sha都是可以的,只不过md5或者sha都是非对称加密,效率没有用hash高。这里我用的是hutoool工具的fnvHash,可以转成32位的10进制;之后再将10进制转成62进制进一步缩短字符长度。
// 计算出长链的hash
int fnvHash = HashUtil.fnvHash(longChain);
// 10进制转62进制短链字符串 "1eDpPm"
String shortChain = DecimalUtil.decimalTo62Base(fnvHash);
将长链对应短链map关系保存,可以保存到Redis,也可以保存到Mysql等数据库中。
CREATE TABLE `chain` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`long_chain` varchar(255) DEFAULT NULL COMMENT '长链',
`short_chain` varchar(255) DEFAULT NULL COMMENT '短链',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='长链->短链表';
当前端发送访问短链请求时,先去找到短链对应长链,将重定向请求返回浏览器,浏览器再去请求长链。
/**
* 短链重定向
*/
@GetMapping("/a/{shortChain}")
public void query(@PathVariable String shortChain, HttpServletResponse response) {
// 数据库查询对应长链
Chain chain = chainMapper.selectOne(new LambdaQueryWrapper<Chain>().eq(Chain::getShortChain, shortChain));
String longChain = chain.getLongChain();
//编码,防止url有中文
String encodeLongChain = URLUtil.encode(longChain);
// 拼接域名、端口、访问文件前缀
String url = "http://localhost:19090/file/common"+encodeLongChain;
//重定向
//response.sendRedirect(encodeUrl);
response.setStatus(302);
response.setHeader("location",url);
}
解决方法:
当需要统计同一篇文章不同人分享时的点击量,这时长链和短链的对应关系就是一对多了,在生成短链的时候就需要把用户的ID加到长链上了。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。