一、背景

现在在各种圈的产品各种推广地址,由于URL地址过长,不美观、不方便收藏、发布、传播以及各种发文字数限制等问题,微信、微博都在使用短链接技术。最近由于使用的三方的生成、解析短链接服务开始限制使用以及准备收费、不方便统计分析、不方便流控等问题,决定自建一个短地址服务。

二、原理

比如,http://a.b.com/15uOVS 这个短地址

第1步,浏览器请求这个地址

第2步,通过DNS后到短地址服务端,还原这个短地址对应的原始长地址。

第3步,请求http 301 或302到原始的长地址上

第4步,浏览器拿到原始长地址的响应response

三、实现

短地址服务的核心是短地址和长地址的转化映射算法。

最简单的算法是把原来的长地址做MD5摘要记为key,长地址记为value。把key value放入服务端缓存中比如redis中。

反向解析时通过URL解决出key来,比如上面的短地址key = 15uOVS 。然后通过key去缓存中获取原始长地址value实现URL地址还原。

MD5摘要有几个明显的问题:

1、短地址的长度受限,比如MD5后的数据长度是32位,需要进行分段循环处理,使短地址足够短

2、MD5的哈希碰撞问题,有一定的概率重复,解决此问题,需要不断的提升算法的复杂度,有些得不偿失

当然不止MD5实现算法比较多,大家可以自行谷歌。

笔者的实现原理如下:

1、新建一张表,主要字段包括自增ID【这里有个小技巧,可以给自增ID设置一个漂亮的起步值,使短地址码随机性更好一些,不建议从0开始自增,比如alter table mapping_info  AUTO_INCREMENT=1112345612;】,原始长地址URL等,做一个自增的10进制长整型短地址key,然后把key转化成62进制,映射到0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz这62个字符上,做成6位的短链接码,如开头的例子15uOVS,【6位62进制数,对应的号码空间为62的6次方,约等于568亿,即可以生成586亿的短网址,基本能满足需求】。

2、把短地址码及长地址,通过key value的形式放入redis和数据库中。

3、写一个过滤器ShortUrlMappingFilter过滤器(为什么是过滤器,因为过滤器是对请求进行过滤转发的,不明白自己谷歌)的执行order设为第一个执行,即值最小。

注: 拦截器、过滤器、监听器的执行顺序   --->   监听器 > 过滤器 > 拦截器 > controller执行 > 拦截器 > 过滤器 > 监听器

相关核心代码如下:

(一) 、ShortUrlMappingFilter过滤器如下:

/**

* @author xuzhujack

**/

public class ShortUrlMappingFilter implements Filter {

private static final Logger LOGGER = LoggerFactory.getLogger(ShortUrlMappingFilter.class);

private static final int shortUrlKeyLength = 6;

@Override

public void init(FilterConfig filterConfig) throws ServletException {

LOGGER.info("ShortUrlMappingFilter init ...........");

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

LOGGER.info("ShortUrlMappingFilter url mapping start......");

HttpServletRequest request = (HttpServletRequest) servletRequest;

HttpServletResponse response = (HttpServletResponse) servletResponse;

BeanFactory factory = WebApplicationContextUtils

.getRequiredWebApplicationContext(request.getServletContext());

ShortUrlService shortUrlService = (ShortUrlService) factory.getBean("shortUrlService");

if(request.getRequestURI().substring(1).trim().length()== shortUrlKeyLength){

ShortUrlDto query = new ShortUrlDto();

query.setId(ShortUrlUtils.base62Decode(request.getRequestURI().substring(1).trim()));

ShortUrl shortUrl = shortUrlService.queryShortUrl(query);

if (shortUrl == null) {

LOGGER.error("ShortUrlMappingFilter shortUrl is null ...........dto is {}", query);

throw new ServletException();

} else {

String srcUrl = shortUrl.getSrcUrl();

LOGGER.info("ShortUrlMappingFilter shortUrl is not null .shortUrl is {}...........dto is {}", shortUrl, query);

response.sendRedirect(srcUrl);

}

}else{

filterChain.doFilter(request, response);

LOGGER.info("非短链接正常后续的doFilter..........");

}

}

@Override

public void destroy() {

}

}

(二)、 ShortUrlMappingFilter在项目的启动主类中增加如下配置:

@Bean

public FilterRegistrationBean contextFilterRegistrationBean2() {

FilterRegistrationBean registrationBean = new FilterRegistrationBean();

registrationBean.setFilter(new ShortUrlMappingFilter());

registrationBean.addUrlPatterns("/*");

registrationBean.setName("ShortUrlMappingFilter");

registrationBean.setOrder(0);

return registrationBean;

}

(三)、62进制和10进制的相互转换

/**

* 将数字转为62进制

* @param num Long 型数字

* @return 62进制字符串

*/

public static String base62Encode(long num) {

String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

StringBuilder sb = new StringBuilder();

int remainder = 0;

int scale = 62;

while (num > scale - 1) {

remainder = Long.valueOf(num % scale).intValue();

sb.append(chars.charAt(remainder));

num = num / scale;

}

sb.append(chars.charAt(Long.valueOf(num).intValue()));

String value = sb.reverse().toString();

return StringUtils.leftPad(value, 6, '0');

}

/**

* 62进制字符串转为数字

* @param str 编码后的62进制字符串

* @return 解码后的 10 进制字符串

*/

public static long base62Decode(String str) {

String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

int scale = 62;

str = str.replace("^0*", "");

long num = 0;

int index = 0;

for (int i = 0; i < str.length(); i++) {

index = chars.indexOf(str.charAt(i));

num += (long) (index * (Math.pow(scale, str.length() - i - 1)));

}

return num;

}

java 短链接url_Java 网址短链接服务原理及解决方案相关推荐

  1. Java 网址短链接服务原理及解决方案

    Java 网址短链接服务原理及解决方案 参考文章: (1)Java 网址短链接服务原理及解决方案 (2)https://www.cnblogs.com/xuzhujack/p/11202364.htm ...

  2. java短链接_Java 网址短链接服务原理及解决方案

    一.背景 现在在各种圈的产品各种推广地址,由于URL地址过长,不美观.不方便收藏.发布.传播以及各种发文字数限制等问题,微信.微博都在使用短链接技术.最近由于使用的三方的生成.解析短链接服务开始限制使 ...

  3. java 短连接+MD5加密短链接

    java 短连接+MD5加密短链接 import java.security.MessageDigest; public class ShotUrlUtil { public static void ...

  4. 短网址短链接哪个好用?2021年最好的缩短链接短网址推荐

    短网址,又称短链接,英文名为Short URL,是一种形式上比较短的网址,使用跳转到方式代替长网址链接,形式美观,而且更容易分享.最出名的短网址服务有百度短网址dwz.cn.新浪微博t.cn.腾讯ur ...

  5. 阿里云短信功能网址链接

    阿里云短信功能网址链接: https://dysms.console.aliyun.com/dysms.htm?spm=5176.doc59210.2.11.7XsCqe#/develop/api

  6. URLshorting网址短链接PHP源码 开源源码

    介绍: 一个url网址缩短平台. 支持发送密语. 安装方法: 1.下载源码. 2.上传至你的网站根目录. 3.访问网站域名填写mysql等信息进行安装 4.修改网站伪静态配置: Nginx: if ( ...

  7. 什么是长连接和短连接?(长链接、短链接)什么时候使用长连接、短链接?

    文章目录 什么是长连接和短连接? 什么时候使用长连接.短链接? 定义 适用场景 什么是长连接和短连接? 在HTTP/1.0中默认使用短连接.也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连 ...

  8. 短链接如何为短信营销提效

    短链接是一个营销推广的神器,它可以很大程度上提高推广效率,获取更多的流量和资源.短链如何使用才能助力短信推广,提供短信推广效果 首先我们先了解,短信营销分以下几种类型: (1)拉新 :可以向新用户发送 ...

  9. 短地址短链接免费接口:缩短链接地址。可用于缩短链接场景,如:电子发票链接,促销活动链接,新闻文章链接等

    短地址短链接接口服务,申请后即可免费使用,提供全接口服务,缩短链接地址,广泛应用于缩短链接场景,如:电子发票链接,促销活动链接,新闻文章链接等. 使用说明: 1.以下短地址接口开发资料供开发技术人员参 ...

最新文章

  1. 吴恩达机器学习视频及答案2018
  2. 清华自研深度学习框架「计图」开源!多项任务性能超过PyTorch
  3. Oracle中的单值函数
  4. 北京大学Tensorflow2.0笔记
  5. mysql数据库sysdate_MySql数据库知识点复习
  6. python fortran混合编程_python调用fortran模块
  7. 淘宝分布式NOSQL框架:Tair
  8. 华为布局智慧屏的背后
  9. 记录repast4py环境配置
  10. iSCSI部署网络存储
  11. 告别户外弱网困扰,4G多卡聚合设备增强弱网环境下应急救援信号
  12. [源码和文档分享]基于JAVA的实现学生卡管理系统
  13. 新冠疫情防控背后有哪些鲜为人知的技术?
  14. 如何切换不同的python环境
  15. 基于STM32F030驱动MQ7一氧化碳传感器
  16. 反诈民警揭秘电信网络诈骗实施的全流程
  17. HTML5期末大作业:在线电影网站设计——网上电影票预订网站 HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码
  18. 返乡人员信息登记管理系统,助力精准管控
  19. 对话李斌:无需纠结是否在硅谷造车 特斯拉有的功能蔚来全有
  20. 豆瓣电影Top 250排行榜海报图片下载

热门文章

  1. 12 大 AI App 技术创意,教你如何在 2020 年赚到钱
  2. 任正非:华为鸿蒙将比安卓快 60%;小米回应主题侵权;VS Code 1.36发布​ | 极客头条...
  3. Unity 和腾讯游戏成立联合创新实验室:从技术创新探索游戏产品新模式和概念
  4. 软件开发者只要会敲代码就可以了?
  5. 程序员就要独“一”无“二”
  6. 80 后技术人的中年危机
  7. matlab复数向极坐标转换_Matlab 图像转极坐标系
  8. html中怎么远程控制小车,利用ESP8266远程控制小车 求大佬帮忙加段程序
  9. linux内核机制是什么,linux内核slab机制分析
  10. oracle统计信息导出与导入目的,Oracle统计信息的导出与导入