阿里云服务器免费领卷啦。

捡代码论坛-最全的游戏源码下载技术网站!

 找回密码
 立 即 注 册

QQ登录

只需一步,快速开始

搜索
关于源码区的附件失效或欺骗帖, 处理办法
查看: 2068|回复: 0

长URL转短连接的简单设计与实现

[复制链接]

4208

主题

210

回帖

12万

积分

管理员

管理员

Rank: 9Rank: 9Rank: 9

积分
126084
QQ
发表于 2017-3-21 09:19:28 | 显示全部楼层 |阅读模式

非常多的时候,我们不想在分享的时候采用长长的链接,主要的原因有:

  • URL太长占显示空间、难于输入,转成二维码点点小,难于识别
  • 长的URL提供的信息太多,不利于信息安全,甚至容易造成倒库
  • 其他理由......

今天的理由不是重点,重点是如何用一点点代码实现这个短链接的生成。

我们的注意点有:

  • 生成的短链接地址长度可调整,毕竟不能因为4位、5位、6位的长度变化就让我们重新写一套程序
  • 要有防冲突处理机制,不能因为算法导致两个长链接地址生成的短地址一样就把前一个覆盖掉
  • 有时候,一个地址用过之后觉得不需要使用了,哪么这个地址失效之后,短地址可以有效收回。

首先设计接口



  1. /**
  2. * Created by luoguo on 2017/3/16.
  3. */
  4. public interface UrlShortener {
  5.     /**
  6.      * 设置产生短链接长度
  7.      * @param length
  8.      * @return
  9.      */
  10.     void setLength(int length);

  11.     /**
  12.      * 返回短链接长度
  13.      * @return
  14.      */
  15.     int getLength();

  16.     /**
  17.      * 返回指定地址对应的短链接
  18.      * @param url
  19.      * @return
  20.      */
  21.     String get(String url);

  22.     /**
  23.      * 存储对应关系
  24.      * @param url
  25.      * @param shortUrl
  26.      */
  27.     void put(String url, String shortUrl);
  28.     /**
  29.      * 到库里查看是不是存在映射,如果不存在返回null
  30.      * @param shortUrl
  31.      * @return
  32.      */
  33.     String seek(String shortUrl);

  34.     /**
  35.      * 据地址产生短地址
  36.      * @param url
  37.      * @return
  38.      */
  39.     String generate(String url);

  40.     /**
  41.      * 根据地址和种子产生一个短地址
  42.      * @param url
  43.      * @param seed
  44.      * @return
  45.      */
  46.     String generate(String url, int seed);
  47.     /**
  48.      * 清除指定URL的短链接信息
  49.      * @param url
  50.      */
  51.     void clean(String url);

  52.     /**
  53.      * 清除指定时间以前没有使用的所有短链接
  54.      * @param date
  55.      */
  56.     void clean(Date date);
  57. }
复制代码
只是个示例,注释比较简陋,接下来是抽象类实现,把公共的内容放这里
  1. import java.util.Random;

  2. /**
  3. * Created by luoguo on 2017/3/16.
  4. */
  5. public abstract class AbstractUrlShortener implements UrlShortener {
  6.     public static char[] VALID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
  7.     private static Random random = new Random(System.currentTimeMillis());
  8.     protected int length = 4;

  9.     public AbstractUrlShortener() {

  10.     }

  11.     public AbstractUrlShortener(int length) {
  12.         this.length = length;
  13.     }

  14.     public void setLength(int length) {
  15.         this.length = length;
  16.     }

  17.     public int getLength() {
  18.         return length;
  19.     }

  20.     public String get(String url) {
  21.         String sortUrl = seek(url);
  22.         if (sortUrl == null) {
  23.             sortUrl = generate(url);
  24.             put(url, sortUrl);
  25.         }
  26.         return sortUrl;
  27.     }

  28.     public String generate(String url, int seed) {
  29.         char[] sortUrl = new char[length];
  30.         for (int i = 0; i < length; i++) {
  31.             sortUrl[i] = VALID_CHARS[seed % VALID_CHARS.length];
  32.             seed = random.nextInt(Integer.MAX_VALUE) % VALID_CHARS.length;
  33.         }
  34.         return new String(sortUrl);
  35.     }

  36.     public String generate(String url) {
  37.         String shortUrl;
  38.         shortUrl = generate(url, random.nextInt(Integer.MAX_VALUE));
  39.         while (seek(shortUrl) != null) {
  40.             shortUrl = generate(url, random.nextInt(Integer.MAX_VALUE));
  41.         }
  42.         put(url, shortUrl);
  43.         return shortUrl;
  44.     }

  45. }
复制代码


实际的需要在数据库层实现,这里在内存里面存储的实现一个意思一下

  1. import java.util.Date;
  2. import java.util.Map;
  3. import java.util.concurrent.ConcurrentHashMap;

  4. /**
  5. * 内存存储的实现
  6. * <p>
  7. * Created by luoguo on 2017/3/16.
  8. */
  9. public class UrlShortenerMemory extends AbstractUrlShortener {
  10.     private Map<String, String> url2ShortUrl = new ConcurrentHashMap<String, String>();
  11.     private Map<String, String> shortUrl2Url = new ConcurrentHashMap<String, String>();

  12.     public UrlShortenerMemory() {
  13.         super();
  14.     }

  15.     public UrlShortenerMemory(int length) {
  16.         super(length);
  17.     }

  18.     public void put(String url, String shortUrl) {
  19.         url2ShortUrl.put(url, shortUrl);
  20.         shortUrl2Url.put(shortUrl, url);
  21.     }

  22.     public String seek(String shortUrl) {
  23.         return shortUrl2Url.get(shortUrl);
  24.     }

  25.     public void clean(String url) {
  26.         String sortUrl = url2ShortUrl.get(url);
  27.         if (sortUrl != null) {
  28.             url2ShortUrl.remove(url);
  29.             shortUrl2Url.remove(sortUrl);
  30.         }
  31.     }

  32.     public void clean(Date date) {
  33.         throw new UnsupportedOperationException();
  34.     }

  35. }
复制代码
弄点测试代码,试试看效果怎么样

  1. public class UrlShortenerTest {
  2.     public static void main(String[] args) {
  3.         for(int j=1;j<10;j++) {
  4.             UrlShortener urlShortener = new UrlShortenerMemory(j);
  5.             for (int i = 0; i < 5; i++) {
  6.                 System.out.println(urlShortener.get("http://www.tinygroup.org"));
  7.             }
  8.             System.out.println();
  9.         }
  10.     }
  11. }
复制代码


这里是运行结果

  1. T
  2. Q
  3. l
  4. i
  5. I

  6. 0R
  7. VB
  8. fN
  9. so
  10. Nw

  11. fw1
  12. fpu
  13. WT7
  14. pNL
  15. M5V

  16. 0cZF
  17. H09A
  18. AjYM
  19. 1AMf
  20. sdkz

  21. USsgK
  22. ZMn9U
  23. 7S48u
  24. oBb1L
  25. yB14g

  26. DRVGWg
  27. gh3oJa
  28. BapdY7
  29. yJgcZj
  30. mivGN3

  31. TEiQG2M
  32. 8SkokOY
  33. NZww5GT
  34. fxloZ0R
  35. hkiOpID

  36. 3ZpdIYrF
  37. eFlSSDyd
  38. bB4RCFgE
  39. 25mceTMK
  40. AAJ2Lp6S

  41. 5IUVoFSqZ
  42. zHZeuZljY
  43. njCGDBKVs
  44. IgH21Tg5V
  45. WvGCy5ZtE
复制代码


感觉还可以,当然里面还有一些不完善的地方

  • 当产生的数量达到一定程度的时候,再获取时由于冲突比较大,导致性能会降低
  • 因此如果是小型系统,建议采用4个长度,大型系统建议采用6个长度
  • 现在还没有多长时间之后自动失效的API,建议添加
  • 需要实现支持序列化的方案
  • 现在没有同步处理,实际实现中需要考虑

这个只是化几分钟展示一个思路,并没有经过系统的思考的验证,正式系统请慎重使用。

更多精彩技术博文,请看本人博客空间

















00

捡代码论坛-最全的游戏源码下载技术网站! - 论坛版权郑重声明:
1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与捡代码论坛-最全的游戏源码下载技术网站!享有帖子相关版权
3、捡代码论坛版权,详细了解请点击。
4、本站所有内容均由互联网收集整理、网友上传,并且以计算机技术研究交流为目的,仅供大家参考、学习,不存在任何商业目的与商业用途。
5、若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。 我们不承担任何技术及版权问题,且不对任何资源负法律责任。
6、如无法链接失效或侵犯版权,请给我们来信:jiandaima@foxmail.com

回复

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立 即 注 册

本版积分规则

技术支持
在线咨询
QQ咨询
3351529868

QQ|手机版|小黑屋|捡代码论坛-专业源码分享下载 ( 陕ICP备15015195号-1|网站地图

GMT+8, 2024-3-29 16:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表