短信被截断?5分钟用Java打造企业级短链服务

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 短链接技术背景

有没有接收到类似上图的推广或促销短信?之前不以为然,不就是一个网址么?也没有关心。

直到最近做了一个项目,用户提交资料以后,审核完成后,需要短信通知用户,引导用户点击链接查看结果。简单的以为就是放一个链接就好了,结果再设计评审的时候,有老司机提出来:链接太长会被短信分成两条发送,需要用到短链接。短链接也正式进入我的视野。

在短信营销场景中,运营商通常将短信长度限制在70字符以内;微信小程序分享卡片对URL长度有严格限制;微博等社交平台也会自动截断长链接。短链接技术通过将原始长URL压缩为6-8位字符的短码,完美解决这些场景的URL展示问题。

02 核心实现原理

无论任何看似简单展示,背后都有你想象不到的技术支撑。曾经一个同事有非常严重的职业病,他说每次点击一个按钮或者打开网页,都会不自觉的想像背后的处理逻辑。甚至因此变的胆小,觉得他的每一步操作都会泄露自己的隐私被第三方采集。

短链接是怎么实现的呢?

  • 映射机制:建立短码与原始URL的键值对映射
  • 重定向技术:服务端返回302状态码实现跳转,重定向到原始的URL
  • 编码算法:生成短码(a-z,A-Z, 0-9)

其中短码的生成,可以自定义生成,也可以通过编码算法将原始链接转化成短码。

03 最佳实践

3.1 随机算法生成短码

利用JDK 手搓方法

java 复制代码
@Test
void test01() {
    String BASE_SEED = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    int len = BASE_SEED.length();

    Random random = new Random();
    StringBuffer codeBuffer = new StringBuffer();
    for (int i=0; i< 6; i++) {
        codeBuffer.append(BASE_SEED.charAt(random.nextInt(len) - 1));
    }

    System.out.println(codeBuffer);
    // 结果 cNrt5D
}

借助工具类 hutool

依赖

xml 复制代码
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.35</version>
</dependency>

代码

java 复制代码
@Test
void test02() {
    System.out.println(RandomUtil.randomString(6));
    // 结果:yNc2sD
}

无论是手搓还是调用第三方的工具,都是利用随机函数获取种子拼接目标数据。随机函数的好处,就是你每次生成的短码都不一样。

3.2 哈希值转换

java 复制代码
@Test
void test03() {
    String BASE_SEED = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    int len = BASE_SEED.length();

    String originUrl = "https://mp.weixin.qq.com/s/Ee-6vh2s9Chi1NATRq-yVg";
    int hash = HashUtil.murmur32(originUrl.getBytes(StandardCharsets.UTF_8));
    System.out.println(hash);
    StringBuilder sb = new StringBuilder();
    while (hash > 0) {
        sb.insert(0, BASE_SEED.charAt(hash % len));
        hash /= len;
    }
    System.out.println(sb);
    // 固定值:bokmy0

哈希值的的好处就是同一个链接生成的短码是相同的,哈希存在哈希冲突,不同的链接可能会生成相同的短码。

3.2 建立映射关系

映射关系需要存储在数据库中,可以选择关系型数据库mysql等、也可以选择非关系型数据库Redis等。

以mysql为例,创建库表:

sql 复制代码
CREATE TABLE `short_url_mapping` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `short_code` varchar(8) DEFAULT NULL COMMENT '短码',
  `origin_url` varchar(2048) NOT NULL COMMENT '原始链接',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `expire_time` datetime DEFAULT NULL COMMENT '过期时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `short_code` (`short_code`),
  KEY `idx_short_code` (`short_code`) COMMENT '短码索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

查找映射关系:

sql 复制代码
SELECT m.origin_url, m.expire_time FROM short_url_mapping m WHERE m.short_code='bokmy0';

查询结果:原始链接和过期时间,如果过期,根据业务需要是否丢弃原始链接。

3.3 重定向技术

在Java Web开发中,页面跳转技术常见的是重定向(Redirect)。

短链接为:ws.cc/bokmy0

原始链接:https://mp.weixin.qq.com/s/Ee-6vh2s9Chi1NATRq-yVg

java 复制代码
@Controller
public class ShortController {

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

    @Autowired
    private ShortUrlService shortUrlService;

    @RequestMapping(value = "/{code}", method = {RequestMethod.GET})
    public ModelAndView index(@PathVariable String code){
        try {
            String url = shortUrlService.getShortUrl(code);
            if (StringUtils.isNotEmpty(url)) {
                return new ModelAndView(new RedirectView(url));
            }
        }catch (Exception ex){
            LOGGER.error("view error.",ex);
        }
        return new ModelAndView("404");
    }
}

这样就可以访问ws.cc/bokmy0时,直接跳转到https://mp.weixin.qq.com/s/Ee-6vh2s9Chi1NATRq-yVg

04 技术优势

  • 规避平台限制:

    解决短信/社交媒体字符限制(如短信70字符、Twitter 280字符,避免长URL被截断导致失效(如微信自动折叠超长链接)等

  • 提升系统安全性:

    隐藏原始URL参数,防止暴露API路径或敏感信息(如用户ID、Token);支持动态封禁恶意链接(只需禁用短码映射,无需修改原始资源)

  • 降低传输成本:

    减少网络请求数据包大小(尤其对低速网络环境友好),节省短信计费成本(每70字符计1条短信,缩短后通常仅占1条)

05 典型的应用场景

场景 长链接痛点 短链解决方案
电商促销短信 商品URL含参数超长被截断 短链节省空间且支持UTM参数跟踪
小程序分享卡片 微信对分享链接长度敏感 短链保障卡片正常渲染
线下广告投放 用户手动输入长URL易出错 短链+二维码提高转化率
API文档调用示例 示例URL暴露内部接口结构 短链隐藏真实路径提升安全性

06 小结

通过短链接技术,企业不仅能解决基础的技术限制问题,更能深度挖掘数据价值、优化用户体验,最终实现降本增效与业务增长的双重目标。

你们平时有没有用过,或者点击过短链接呢?评论区讨论。

相关推荐
懒惰的橘猫11 分钟前
配置Hadoop集群-测试使用
java·ide·eclipse
破烂公司一级特派员1 小时前
互联网大厂Java面试实录:从基础到微服务的深度考察
java·spring boot·微服务·八股文·面试技巧
Linux运维老纪1 小时前
微服务6大拆分原则
java·运维·微服务
黄俊懿1 小时前
【深入理解SpringCloud微服务】手写实现一个微服务分布式事务组件
java·分布式·后端·spring·spring cloud·微服务·架构师
在未来等你1 小时前
互联网大厂Java求职面试:基于RAG的智能问答系统设计与实现-2
java·智能问答·milvus·向量数据库·rag·spring ai
lcw_lance1 小时前
TOGAF 企业架构介绍(4A架构)
架构·系统架构·数据库架构
Themberfue1 小时前
RabbitMQ ②-工作模式
开发语言·分布式·后端·rabbitmq
Jia ming1 小时前
Linux 内核对 ARM 大小核架构的支持
linux·arm开发·架构
极小狐1 小时前
如何使用极狐GitLab 软件包仓库功能托管 helm chart?
java·linux·服务器·数据库·c#·gitlab·maven
有梦想的攻城狮2 小时前
spring中的@Inject注解详情
java·后端·spring·inject