目录
前言
什么是短链接
为什么要用短链接(引用)
如何生成短链接
实现
代码
演示
前段时间做支付的时候,要生成可供微信和支付宝扫描的支付二维码,二维码里存储的也就是一个链接,但是可能是因为链接比较长的缘故,总是被微信拦截。
然后就换成了微信官方的长链接转短链接,好不容易弄好了,发现支付宝扫的话会拦截,两家果真是水火不容。。。
有问题就解决问题呗,那我换成第三方的好了,但是网上一般的第三方短链接服务平台都不会被微信接纳,那就只能找比较知名的,比如新浪、百度、谷歌,我首先试了新浪的,完美,终于让微信和支付宝都满意了。
然后就在前几周,测试人员忽然找我说二维码出不来了。。我真是心力交瘁,去新浪官方一看你说气不气,在11号的时候这个接口下线了。。。
靠别人永远靠不住。。。那就只能靠自己了!
没有接触过这种业务的小伙伴可能会问什么是短链接?长链接好好地,干嘛要把它转成短链接?咋就能转成短链接呢?
下面我们简单介绍一下短链接的相关知识。
顾名思义,就是将长网址缩短到一个很短的网址,用户访问这个短网址可以就可以访问到原本的长网址。这样可以达到易于记忆、转换的目的。
比如一个百度图片的搜索网址是这样的:http://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%CD%BC%C6%AC&fr=ala&ala=1&alatpl=others&pos=0
够长吧,那我们用一些短网址服务平台来进行短网址生成:
- 百度短网址服务生成的短网址:https://dwz.cn/afLO9WNV
- 新浪免费版短网址服务生成的短网址:http://1t.click/atFy
以及一些第三方的:
- (https://dwz3.cn/)生成的短网址:https://0x9.me/8NhQJ
- (http://www.h5ip.cn/)生成的短网址:http://h5ip.cn/SmDX
看到没有,一个那么长的网址,确被缩短到这么短,而且每个平台生成的都不一样,缺都可以访问到我们原本那个长长的网址。以上生成的网址有些可能是永久的,有些可能一段时间就过期了。
1、新浪微博
我们在新浪微博上发布网址的时候,微博会自动判别网址,并将其转换,例如:https://t.cn/RuPKzRW。为什么要这样做的?
这是因为微博限制字数为140字一条,那么如果我们需要发一些链接上去,但是这个链接非常的长,以至于将近要占用我们内容的一半篇幅,这肯定是不能被允许的或者说用户体验很差的,所以短网址应运而生了,短网址这种服务可以说是在微博出现之后才流行开来的!往下看:
(1)首先,我先发一条微博带有一个URL地址:
(2)然后,看他转换之后显示的效果是什么样子的哪?
(3)查看对应页面元素的HTML源码如下:
(4)可以看出:https://blog.csdn.net/xlgen157387/article/details/79863301 被转换为:http://t.cn/RuPKzRW,此时你访问http://t.cn/RuPKzRW是可以定位到https://blog.csdn.net/xlgen157387/article/details/79863301,也就是实现了转换。
2、短网址二维码
网址在转换成短网址时,也可以生成相应的短网址二维码,短网址二维码的应用,二维码核心解决的是跨平台、跨现实的数据传输问题;而且二维码跟应用场景结合之后,所能解决的问题会越来越多。
(1)短网址二维码相比短链接更方便,能少输入,尽量少输入,哪怕只是少点一下键盘,都是有意义的。
(2)二维码只是扫描一个简单的链接,打开的却是一个世界。想象一下,用手机购买售货机里商品,二维码扫描是略快于从用手机找到该售货机并找到该商品的,而且这种操作相对于搜索/查找而言不是更优雅吗?
(3)所有商超里面的商品,都是使用条码来确定商品的唯一性的,去买单的时候都是扫描条码。试想,如果里面加入了更多产品的生产日期、厂家、流转途径、原材料等等信息,是不是厉害了呢?特别是针对食品信息的可追溯上,二维码应用场景更广泛。
除了上述场景中,我们将长地址转换为短地址的使用场景的优点(压缩URL长度)之外,短地址还具有很多实际场景中的优点,例如:(1)节省网址长度,便于社交化传播,一个是让URL更短小,传播更方便,尤其是URL中有中文和特殊字符,短网址解决很长的URL难以记忆不利于传播的问题;
(2)短网址在我们项目里可以很好的对开放以及对URL进行管理。有一部分网址可以会涵盖性、暴力、广告等信息,这样我们可以通过用户的举报,完全管理这个连接将不出现在我们的应用中,对同样的URL通过加密算法之后,得到的地址是一样的;
(3)方便后台跟踪点击量、地域分布等用户统计。我们可以对一系列的网址进行流量,点击等统计,挖掘出大多数用户的关注点,这样有利于我们对项目的后续工作更好的作出决策;
(4)规避关键词、域名屏蔽手段、隐藏真实地址,适合做付费推广链接;
(5)当你看到一个淘宝的宝贝连接后面是200个“e7x8bv7c8bisdj”这样的字符的时候,你还会觉得舒服吗。更何况微博字数只有140字,微博或短信里,字数不够,你用条短网址就能帮你腾出很多空间来;
网上比较流行的算法有两种 自增序列算法、 摘要算法
这里我也没去专门很细的研究,着急拿来用,后续有时间再去深入吧,有兴趣的小伙伴可以看一下以下博客:
面试必备:如何将一个长URL转换为一个短URL?
短网址(short URL)系统的原理及其实现
好了,说了这么多,终于到实现的部分了,其实短网址生成服务基本的实现流程都是一样的,不一样的知识短网址生成的算法不同而已,下面是一个短网址系统基本的实现,我这里是存在redis中比较方便快捷,大家也可以选择存入mysql等。
这里的案例场景模仿我遇到的支付问题
案例是基于springboot项目,其他框架可能要做适当修改
OrderPayController:项目内生成二维码的接口,这里简化,只是生成链接,未转变为二维码,想转为二维码的可以看:【二维码】——生成二维码并转为base64
/** * @author: WangZhiJun * @create: 2019-09-21 12:31 **/ @RestController @RequestMapping("/api/v1/order") public class OrderController { private static final String SHORT_URL = "shortUrl:"; @Resource private RedisTemplate
redisTemplate; /** * 系统内生成支付二维码接口 */ @GetMapping(value = "/payOrder") public String pay(@RequestParam String orderId) { String orderName = "XXSuperMarketPay"; BigDecimal orderMoney = new BigDecimal(100); System.out.println("订单"+orderId+orderName+"需支付:"+orderMoney+"元"); String wxPayUrl = "http://localhost:8080/wx/pay/pay?orderId="+orderId+"&orderName="+orderName+"&orderMoney="+orderMoney; String shortUrl = ShortUrlUtils.shortUrl(wxPayUrl); System.out.println("生成的微信支付链接为:"+wxPayUrl); System.out.println("生成的短链接为:"+ shortUrl); //存入redis或者数据库,键值为六位数的短链接 redisTemplate.opsForValue().set(SHORT_URL + shortUrl, shortUrl, 1, TimeUnit.HOURS); //这里我的业务场景中是生成二维码,这里简化为链接 return "http://localhost:8080/url/" + shortUrl; } } WxPayController:模仿微信支付官方接口
/** 假设这是微信支付的接口 * @author: WangZhiJun * @create: 2019-09-21 12:31 **/ @RestController @RequestMapping("/wx/pay") public class WxPayController { /** * 模仿微信支付API */ @GetMapping(value = "/pay") public void paySuccess(@RequestParam String orderId, @RequestParam String orderMoney, @RequestParam String orderName) { System.out.println("订单"+orderId+orderName+"支付:"+orderMoney+"元"); System.out.println("支付成功"); } }
UrlController:短码转发,将短码对应的长链接取出并重定向到长链接
/** * @description: 短网址转发 * @author: WangZhiJun * @create: 2019-09-21 12:20 **/ @RestController @RequestMapping("/url") public class UrlController { private static final String SHORT_URL = "shortUrl:"; @Resource private RedisTemplate
redisTemplate; @GetMapping(value = "/{shortUrl}") public void getInvoiceUrl(@PathVariable(required = false) String shortUrl, HttpServletResponse response) { String url = (String) redisTemplate.opsForValue().get(SHORT_URL + shortUrl); try { //将短链接映射的长链接取出并重定向到长链接 response.sendRedirect(url); } catch (IOException e) { e.printStackTrace(); } } }
长链接转短码的算法主要是使用MD5 算法对原始链接进行加密(这里使用的MD5 加密后的字符串长度为32 位),然后对加密后的字符串进行处理以得到短链接的地址。
import java.security.MessageDigest; /** 短链接生成工具类 * @author WangZhiJun */ public class ShortUrlUtils { /** * 十六进制下数字到字符的映射数组 */ private final static String[] HEXDIGITS = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; /**把inputString加密*/ public static String md5(String inputStr){ return encodeByMD5(inputStr); } /**对字符串进行MD5编码*/ private static String encodeByMD5(String originString){ if (originString!=null) { try { //创建具有指定算法名称的信息摘要 MessageDigest md5 = MessageDigest.getInstance("MD5"); //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算 byte[] results = md5.digest(originString.getBytes()); //将得到的字节数组变成字符串返回 String result = byteArrayToHexString(results); return result; } catch (Exception e) { e.printStackTrace(); } } return null; } /** * 轮换字节数组为十六进制字符串 * @param b 字节数组 * @return 十六进制字符串 */ private static String byteArrayToHexString(byte[] b){ StringBuffer resultSb = new StringBuffer(); for(int i=0;i
> 5; } // 把字符串存入对应索引的输出数组 resUrl[i] = outChars.toString(); } return resUrl; } }
然后访问生成的短码网址:http://localhost:8080/url/vqQjEj,会自动重定向到原本的支付链接
实现效果可以去我的个人主页进行测试:短网址服务
大功告成!