如何自己搭建短链接服务
短链接我们或多或少都使用过,所谓短链接就是根据较长的原链接url生成一段较短的链接,访问短链接可以跳转到对应的原链接,这样做好处在于:1. url更加美观;2. 便于保存和传播;3. 某些网站内容发布有字数限制,短链接可以节约字数。
短链接实现的原理非常简单,可以概括为:
- 为每个原链接生成不重复的唯一短链接
- 将原链接和对应短链接成对保存到数据库
- 访问短链接时,web服务器将目标重定向到对应的原链接
这两天没事用SpringBoot+Redis做了一个短网址服务,支持web方式和api方式创建短网址。
其核心思想就是把生成的短网址与原网址在redis做k-v对应,当短网址k请求到来的时候取出原网址v直接重定向
为了防止短网址冲突,生成短网址的方式是采用获取原网址的md5方式。建议对短网址限时失效防止出现重复问题
代码全在GitHub地址:https://github.com/NiuXiangQian/u
项目过于简单,不准备继续维护
Web效果图
Api方式
post http://127.0.0.1:8080/api/v1/generate?ak=ak_123&sk=sk_123
type application/json
body {
"url":"https://www.baidu.com/s?wd=a&rsv_spt=1&rsv_iqid=0xd1a6a2e5000e2bc1&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=1&rsv_sug2=0&rsv_btype=i&inputT=509&rsv_sug4=509",
"valid":14400
}
参数说明:url 传入的长网址
valid 有效时间(秒),默认四个小时,可以不用穿,-1永久有效
respone {"code": 1,
"success": true,
"msg": "ok",
"data": {
"orgUrl": "https://www.baidu.com/s?wd=a&rsv_spt=1&rsv_iqid=0xd1a6a2e5000e2bc1&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=1&rsv_sug2=0&rsv_btype=i&inputT=509&rsv_sug4=509",
"shortUrl": "http://127.0.0.1:8080/u/ff185ccd0439f762",
"shortTarget": "ff185ccd0439f762",
"validTime": 14400
}
}
核心代码
创建短网址
接口
/**
* 生成一个短链接
* @author nxq
* @param apiGenerateReq:
* @return com.github.niu.u.common.core.R<java.lang.String>
*/
@PostMapping("/generate")
public R<ShortUrlVo> generate(@Valid @RequestBody ApiGenerateReq apiGenerateReq) throws BaseException {
ShortUrlVo shortURL = urlService.generate(apiGenerateReq.getUrl(),apiGenerateReq.getValid());
return R.ok(shortURL);
}
service
@Override
public ShortUrlVo generate(String srcUrl, Long valid) throws BaseException {
if (valid == null){
valid = 60L * 60L *4L ; // 默认有效时间4个小时
}
if (valid!= -1 && valid <0){
throw new BaseException("有效时间非法");
}
srcUrl = srcUrl.trim();
String shortURL = MD5Util.encryptStr( srcUrl);
String key = CommonCache.SHORT_URL+shortURL;
redisTemplate.opsForValue().set(key,srcUrl);
if (valid != -1){ // -1是永久有效
redisTemplate.expire(key,valid, TimeUnit.SECONDS);
}
ShortUrlVo shortUrlVo = new ShortUrlVo();
shortUrlVo.setOrgUrl(srcUrl)
.setShortTarget(shortURL)
.setValidTime(valid)
.setShortUrl(generateShortUrl(shortURL));
return shortUrlVo;
}
接收短网址请求
@GetMapping("/u/{shortUrl}")
public void u(HttpServletResponse response, @PathVariable String shortUrl) throws IOException {
if (StringUtils.isNotBlank(shortUrl)){
String url = redisTemplate.opsForValue().get(CommonCache.SHORT_URL+shortUrl);
if (StringUtils.isNotBlank(url))
if (!(url.startsWith("http://")||url.startsWith("https://"))){
url = "http://"+url;
}
response.sendRedirect(url);
} else{
response.getWriter().write("url is lose efficacy");
}
}
}
更多请查看github上说明