一、为什么要设计短链接,短链接有什么好处?

1、链接变短,在对内容长度有限制的平台发文,可编辑的文字就变多了。

比如:微博,限定了只能发 140 个字,如果一串长链直接怼上去,其他可编辑的内容就所剩无几了,用短链的话,链接长度大大减少,自然可编辑的文字多了不少。

2、我们经常需要将链接转成二维码的形式分享给他人,如果是长链的话二维码密集难识别,短链就不存在这个问题了。

3、链接太长在有些平台上无法自动识别为超链接。

二、短链接实现的原理。

1、请求流程:

首先,我们先看看当当的短链接http://localhost:8060/1J0vEa
它是由两个部分组成
http://localhost:8060短链接系统的域名地址或者IP+端口
1J0vEa:请求参数
请求 http://localhost:8060/1J0vEa 地址后,返回状态如下所示

 2、请求短链接后,浏览器发生了什么?

上图所示短链接系统,返回的状态可以为301或者302。
301代表什么?
301代表的是永久重定向。什么意思呢?
对于GET请求, 301跳转会默认被浏览器cache。也就是说,用户第一次访问某个短链接后,如果服务器返回301状态码,则这个用户在后续多次访问同一短链接地址,浏览器会直接请求跳转地址,而不会再去短链接系统上取!

这么做优点很明显,降低了服务器压力,但是无法统计到短链接地址的点击次数。

302代表什么?
302代表的是临时定向。什么意思呢?
对于GET请求, 302跳转默认不会被浏览器缓存,除非在HTTP响应中通过 Cache-Control 或 Expires 暗示浏览器缓存。因此,用户每次访问同一短链接地址,浏览器都会去短链接系统上取。

这么做的优点是,能够统计到短地址被点击的次数了。但是服务器的压力变大了。

三、短链接实现的方法。

1、MurmurHash 非加密型哈希函数 把链接转成一串数字。

public static String hashToBase62(String str) {int i = MurmurHash.hash32(str);long num = i < 0 ? Integer.MAX_VALUE - (long) i : i;return convertDecToBase62(num);
}

2、由于我们的短链接是由 a-z、A-Z 和 0-9 共 62 个字符可以选择。因此,我们可以由长链接经过hashToBase62方法转成的十进制的数字,转换为一个62进制的数,例如:http://www.cnblogs.com/rjzheng/p/11827426.html 转成 1J0vEa

private static char[] CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};private static int SIZE = CHARS.length;private static String convertDecToBase62(long num) {StringBuilder sb = new StringBuilder();while (num > 0) {int i = (int) (num % SIZE);sb.append(CHARS[i]);num /= SIZE;}return sb.reverse().toString();}

3、短链接生成方法。

@Overridepublic String saveUrlMap(String shortURL, String longURL, String originalURL) {//保留长度为1的短链接if (shortURL.length() == 1) {longURL += DUPLICATE;shortURL = saveUrlMap(HashUtils.hashToBase62(longURL), longURL, originalURL);}//在布隆过滤器中查找是否存在else if (FILTER.contains(shortURL)) {//存在,从Redis中查找是否有缓存String redisLongURL = redisTemplate.opsForValue().get(shortURL);if (redisLongURL != null && originalURL.equals(redisLongURL)) {//Redis有缓存,重置过期时间redisTemplate.expire(shortURL, TIMEOUT, TimeUnit.MINUTES);return shortURL;}//没有缓存,在长链接后加上指定字符串,重新hashlongURL += DUPLICATE;shortURL = saveUrlMap(HashUtils.hashToBase62(longURL), longURL, originalURL);} else {//不存在,直接存入数据库try {urlMapper.saveUrlMap(new UrlMap(shortURL, originalURL));FILTER.add(shortURL);//添加缓存redisTemplate.opsForValue().set(shortURL, originalURL, TIMEOUT, TimeUnit.MINUTES);} catch (Exception e) {if (e instanceof DuplicateKeyException) {//数据库已经存在此短链接,则可能是布隆过滤器误判,在长链接后加上指定字符串,重新hashlongURL += DUPLICATE;shortURL = saveUrlMap(HashUtils.hashToBase62(longURL), longURL, originalURL);} else {throw e;}}}return shortURL;}

四、代码。

实现的代码在github:https://github.com/526606178/shortUrl

本文参考了:

https://www.cnblogs.com/rjzheng/p/11827426.html

https://github.com/zzyybs/bestJavaer/commit/cc48eb0680671e8bb362782c78ed708f93f729d8#diff-7dcf1a9faa4713d5be6358d58e41fdc70b8f399b058d1ac50ea025ba99301cd8

长链接转成短链接的原理和实现详解相关推荐

  1. 带地址参数的长链接转换成短链接分享

    项目中的长链接中有二维码的地址,二维码的地址中又有用户的参数,出现了两个?,分享出去很不好看还有问题,使用了新浪等的长链接转短链接总会截断第二个问号后的数据. 我自己去网站扒了一个长链接转短链接的接口 ...

  2. php将长url转成短链接,php将URL长链接转换短链接的两种方法

    短网址(Short URL) ,顾名思义就是在形式上比较短的网址.在Web 2.0的今天,不得不说,这是一个潮流.目前已经有许多类似服务,借助短网址您可以用简短的网址替代原来冗长的网址,让使用者可以更 ...

  3. SpringBoot-生成短链接(长链接转换成短链接-百度短网址)

    采用Google工具类 一.引入jar <dependency> <groupId>com.google.code.gson</groupId> <artif ...

  4. DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...

  5. Nginx(二):反向代理原理 与 配置文件详解

    相关阅读: Nginx(一):Nginx原理概述 与 安装步骤详解 Nginx(二):反向代理原理 与 配置文件详解 Nginx(三):负载均衡策略 与 Nginx静态服务器 Nginx(四):Ngi ...

  6. DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解

    FROM:http://blog.csdn.net/u012162613/article/details/43221829 @author:wepon @blog:http://blog.csdn.n ...

  7. Spark SQL原理及常用方法详解(二)

    Spark SQL 一.Spark SQL基础知识 1.Spark SQL简介 (1)简单介绍 (2)Datasets & DataFrames (3)Spark SQL架构 (4)Spark ...

  8. java的markword_【转帖】Java工具结构与锁实现原理及MarkWord详解

    Java工具结构与锁实现原理及MarkWord详解 https://www.pianshen.com/article/2382167638/ 我们都知道,Java工具存储在堆(Heap)内存.那么一个 ...

  9. 人脸识别SeetaFace2原理与代码详解

    人脸识别SeetaFace2原理与代码详解 前言 一.人脸识别步骤 二.SeetaFace2基本介绍 三.seetaFace2人脸注册.识别代码详解 3.1 人脸注册 3.1.1 人脸检测 3.1.2 ...

最新文章

  1. Android Activity的onRestart()方法
  2. WebServieces 部署到PocketPC上的问题(SystemNotSupportException)
  3. windows 系统监视器_使用Windows 7中的可靠性监视器对计算机问题进行故障排除
  4. Freeswitch之ASR(语音识别)总结大全
  5. 牛客16437 买铅笔
  6. nacos 开启权限验证后 报错状态 403
  7. oracle data guard闪回,11gR2 Active Data Guard 闪回 - flashback database / snapshot standby - 2
  8. php使用PHPMailer发送邮件示例
  9. Excel与DataGridView的操作示例
  10. python os模块下载_python os模块
  11. AS 中强制类型转换
  12. vue混入html,vue混入(mixins)的应用
  13. 蓝屏dump分析教程,附分析工具WinDbg(x86 x64)6.12.0002.633下载
  14. oracle北京时区,ORACLE中的时区(time zone)
  15. rd640服务器引导,ThinkServer RD640 OS安装手册 V1.4.pdf
  16. 红米手机5获取Root超级权限的步骤
  17. 请确保您已登录客户机操作系统。在客户机中装载虚拟CD驱动器,启动终端,使用tar解压...
  18. 小程序页面生成相应小程序码
  19. 手机端有没有好用的图片识别文字工具值得推荐?
  20. Oracle(三)--数据库建表操作

热门文章

  1. DAG,PDAG,CPDAG定义
  2. SQL - 深入理解MySQL索引之B+Tree
  3. Ecshop 二次开发之 朝花夕拾
  4. 电脑一直蓝屏怎么办?重装系统方法
  5. 实现移动曲面拟合法的数字高程模型内插,数据格式X、Y、Z,数据量大,使用C++语言实现...
  6. python爬取有声小说网站实现自动下载实例
  7. 自由液面的土石坝平面渗流分析
  8. Silverlight 资源的使用
  9. 计算机操作系统(一)
  10. 【Day4】语音识别(音频转文字)