实现结果: 

转换短链接api:

接口:http://127.0.0.1/api?url=urlencode('要缩短的网址')

例如:http://127.0.0.1/api?url=http%3a%2f%2fwww.baidu.com

返回:http://127.0.0.1/baidu

访问短链接即可还原原url;

转换原理: 将原url通过一系列方式,转换成6位短码(只要能不重复,随便怎么方式都行);将长短链接存入数据库,形成一条对应关系;访问短链接的时候,在数据库找到对应的长链接,并通过重定向实现原url的访问;(如果你的转换方式能过还原,也可以不要数据库,但必须保证转换后的短码不能重复)

核心代码参考 :https://www.cnblogs.com/latteyan/articles/5845117.html

实现步骤:

1.创建数据库(shorturl),创建一个表,存储长链接和与之对应的短链接;

CREATE TABLE `link` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',`long_url` varchar(500) DEFAULT NULL COMMENT '长链接',`short_url` varchar(255) DEFAULT NULL COMMENT '短链接',PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

2.搭建springboot项目,搭建方式网上很多,自行查找;下图是项目构建完成的项目结构(public可以忽略):

3.逻辑层代码依次是:

entity:

package com.tips.entity;public class Link {private Integer id;private String longUrl;private String shortUrl;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getLongUrl() {return longUrl;}public void setLongUrl(String longUrl) {this.longUrl = longUrl;}public String getShortUrl() {return shortUrl;}public void setShortUrl(String shortUrl) {this.shortUrl = shortUrl;}
}

dao:

package com.tips.mapper;import com.tips.entity.Link;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface LinkMapper {Link selectByPrimaryKey(Integer id);int insert(Link link);Link findByLongUrl(String longUrl);String findByShortUrl(String shortUrl);
}

service:

package com.tips.service;import com.tips.entity.Link;public interface LinkService {String save(Link link);String restoreUrl(String url);}

service.impl:

package com.tips.service.impl;

import com.tips.entity.Link;
import com.tips.mapper.LinkMapper;
import com.tips.service.LinkService;
import com.tips.util.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class LinkServiceImpl  implements LinkService{@Autowired
    private LinkMapper linkMapper;

    /**
     * 转化url
     * 查询数据库是否已经存在 如果存在就返回数据库对应的短链接,如果不存在就查询一条新纪录并返回新的短链接
     * @param link
     * @return
     */
    @Override
    public String save(Link link) {String shortUrl = "http://127.0.0.1/";
        String longUrl = link.getLongUrl();
        System.out.println(longUrl);
        Link link1 = linkMapper.findByLongUrl(longUrl);
        if(link1 == null) {shortUrl += this.gererateShortUrl(longUrl);
            link.setShortUrl(shortUrl);
            linkMapper.insert(link);
        }else{shortUrl = link1.getShortUrl();
        }return shortUrl;
    }@Override
    public String restoreUrl(String url) {return linkMapper.findByShortUrl(url);
    }/**
     * @param args
     */
    public static void main(String[] args) {String sLongUrl = "http://474515923.qzone.qq.com" ; //长链接
        LinkServiceImpl link = new LinkServiceImpl();
        String result = link.gererateShortUrl(sLongUrl);
        // 打印出结果
       System.out.println("短链接为: "+ result);
    }/**
     * 将长链接转换为短链接
     * @param url
     * @return
     */
    public String gererateShortUrl(String url) {// 可以自定义生成 MD5 加密字符传前的混合 KEY
        String key = "caron" ;
        // 要使用生成 URL 的字符
        String[] chars = new String[] { "a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" ,
                "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" ,
                "u" , "v" , "w" , "x" , "y" , "z" , "0" , "1" , "2" , "3" , "4" , "5" ,
                "6" , "7" , "8" , "9" , "A" , "B" , "C" , "D" , "E" , "F" , "G" , "H" ,
                "I" , "J" , "K" , "L" , "M" , "N" , "O" , "P" , "Q" , "R" , "S" , "T" ,
                "U" , "V" , "W" , "X" , "Y" , "Z"

        };
        // 对传入网址进行 MD5 加密
        String sMD5EncryptResult = MD5Util.MD5(key+url);
        String hex = sMD5EncryptResult;

//        String[] resUrl = new String[4];
//        for ( int i = 0; i < 4; i++) {

            // 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算
            String sTempSubString = hex.substring(2 * 8, 2 * 8 + 8);    //固定取第三组

            // 这里需要使用 long 型来转换,因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用 long ,则会越界
            long lHexLong = 0x3FFFFFFF & Long.parseLong (sTempSubString, 16);
            String outChars = "" ;
            for ( int j = 0; j < 6; j++) {// 把得到的值与 0x0000003D 进行位与运算,取得字符数组 chars 索引
                long index = 0x0000003D & lHexLong;
                // 把取得的字符相加
                outChars += chars[( int ) index];
                // 每次循环按位右移 5 位
                lHexLong = lHexLong >> 5;
            }// 把字符串存入对应索引的输出数组
//            resUrl[i] = outChars;
//        }
        return outChars;
    }
}

util:

package com.tips.util;import java.security.MessageDigest;public class MD5Util { // MD5加码。32位 public static String MD5(String inStr) { MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { System.out.println(e.toString()); e.printStackTrace(); return ""; } char[] charArray = inStr.toCharArray(); byte[] byteArray = new byte[charArray.length]; for (int i = 0; i < charArray.length; i++) byteArray[i] = (byte) charArray[i]; byte[] md5Bytes = md5.digest(byteArray); StringBuffer hexValue = new StringBuffer(); for (int i = 0; i < md5Bytes.length; i++) { int val = ((int) md5Bytes[i]) & 0xff; if (val < 16) hexValue.append("0"); hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } // 可逆的加密算法 public static String KL(String inStr) { // String s = new String(inStr); char[] a = inStr.toCharArray(); for (int i = 0; i < a.length; i++) { a[i] = (char) (a[i] ^ 't'); } String s = new String(a); return s; } // 加密后解密 public static String JM(String inStr) { char[] a = inStr.toCharArray(); for (int i = 0; i < a.length; i++) { a[i] = (char) (a[i] ^ 't'); } String k = new String(a); return k; } // 测试主函数 public static void main(String args[]) { String s = new String("a"); System.out.println("原始:" + s); System.out.println("MD5后:" + MD5(s)); System.out.println("MD5后再加密:" + KL(MD5(s))); System.out.println("解密为MD5后的:" + JM(KL(MD5(s)))); System.out.println("判断是否相同:" + MD5(s).equals(JM(KL(MD5(s))))); }
} 

mapper:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tips.mapper.LinkMapper">
    <resultMap id="BaseResultMap" type="com.tips.entity.Link">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="long_url" jdbcType="VARCHAR" property="longUrl" />
        <result column="short_url" jdbcType="VARCHAR" property="shortUrl" />
    </resultMap>
    <sql id="Base_Column_List">
        id, long_url, short_url</sql>

    <!-- 根据长链接查询 -->
    <select id="findByLongUrl" parameterType="java.lang.String" resultMap="BaseResultMap">
        select<include refid="Base_Column_List" />
        from linkwhere long_url = #{longUrl,jdbcType=VARCHAR}</select>
    <!-- 根据短链接查询 -->
    <select id="findByShortUrl" parameterType="java.lang.String" resultType="java.lang.String">
        select long_url from linkwhere short_url = #{shortUrl,jdbcType=VARCHAR}</select>

    <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select<include refid="Base_Column_List" />
        from linkwhere id = #{id,jdbcType=INTEGER}</select>

    <insert id="insert" parameterType="com.tips.entity.Link">
        insert into link (id, long_url, short_url)values (#{id,jdbcType=INTEGER}, #{longUrl,jdbcType=VARCHAR}, #{shortUrl,jdbcType=VARCHAR})</insert>

</mapper>

controller:

package com.tips.controller;import com.tips.entity.Link;
import com.tips.service.LinkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class LinkController {@Autowiredprivate LinkService linkService;/*** 生成短链接* @param url* @return Caron*/@RequestMapping("/api")@ResponseBodypublic Object save(String url){if (url == null || "".equals(url)){return null;}if(url.startsWith("http://") || url.startsWith("https://")){Link link = new Link();link.setLongUrl(url);return  linkService.save(link);}else{return "网址必须以http或https开头";}}/*** 301跳转* @param url* @return*/@RequestMapping("/{url}")public String restoreUrl(@PathVariable("url") String url){String restoreUrl = linkService.restoreUrl("http://cni.tips/"+url);if(restoreUrl != null && !"".equals(restoreUrl)){return "redirect:"+restoreUrl;}else{return "redirect:http://www.cnilink.com";
//            return  "forward:/404.html";    //如果要访问本地html,@RequestMapping("/{url}")前面必须加一层路径/aa/{url}}}}

application.properties:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com</groupId><artifactId>tips</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>tips</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.2</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

基本所有源码都贴出来了。跑起来试一下呗

springboot 实现长链接转短链接相关推荐

  1. springboot实现长链接转短链接

    自己编写长链接转短链接 原理:将长链接在后台通过转换的方式转成所需的短链接(域名+(项目名)+唯一标识) 长链接转成短链接 /*** 短链接工具类*/ @Component public class ...

  2. 长URL链接转短链接算法

    引言 很多大型网站都加入了短链接的功能.之所以要是使用短链接,主要是因为微博只允许发140 字,如果链接地址太长的话,那么发送的字数将大大减少.短链接的主要职责就是把原始链接很长的地址压缩成只有6 个 ...

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

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

  4. http / 关于长连接和短链接的理解

    HTTP 协议是基于请求 / 响应模式的,因此只要服务端给了响应,本次 HTTP 请求就结束了,也可以理解成 HTTP 是面向请求 / 响应的. TCP 协议是面上连接的. 综上,如果 HTTP 请求 ...

  5. HTTP的长链接和短链接说明

    HTTP的长链接和短链接实际上是TCP的长连接和短链接.首先我们先介绍一下TCP/IP协议组四层模型.其中包括以下: 应用层:HTTP.FTP.DNS.TELNET等协议 传输层:TCP.UDP 网络 ...

  6. java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串...

    java,url长链接生成短链接,短链接生成器,自定义字符串,对字符串md5混合KEY加密,根据短链接获得key值,不重复的随机数,不重复的随机字符串 1 package com.zdz.test; ...

  7. 【短链接】——新浪、百度、搜狐等官方长链接转短链接

    在项目中难免会生成自己的跳转链接,为了简化链接以及防止微信等屏蔽,可以用一些官方的api将自己的链接转为短链接. ConvertShortUrlUtil.java public class Conve ...

  8. C#长链接转短链接(调用新浪api)

     /// <summary>  /// 长链接转短链接  /// </summary>  /// <param name="longUrl"> ...

  9. 我把视频变成链接_如何把长链接变成短链接?3个工具帮你实现

    不管是文章还是视频的链接,很多时候都是长长的一串,如果是发给别人的话,就会显得啰里啰嗦,占用空间大不说,还非常难看,使用起来不方便.其实长链接也是能够变成短链接的,下面就带来三个工具,让链接变得美观又 ...

  10. 微信URL Scheme码+长链接转短链接+短链接通过h5页面跳转到微信小程序

    微信URL Scheme码+长链接转短链接+短链接通过h5页面跳转到微信小程序 --生成微信URL Scheme码-->长链接转换成短链接-->通过短信进行推广-->用户访问营销短信 ...

最新文章

  1. 解决Neither the JAVA_HOME nor the JRE_HOME environment variable is defined问题
  2. Bash功能与使用技巧
  3. 事务,Oracle,MySQL及Spring事务隔离级别
  4. 2016网易实习生编程题:n个骰子的和等于m
  5. sed教程入门与实例练习(一)
  6. 深度学习笔记--多层感知器以及BP算法
  7. web服务器IIS详细错误代码以及解释
  8. 易语言代码转换python_易语言通过文本解析的方式把C代码转换成易代码
  9. Maven下载安装与配置IDEA
  10. ubuntu20.04.4虚拟机 ping不通百度问题解决
  11. 前后端跨语言RSA加解密和签名验证实现(js+python)
  12. MOOS程序解析记录(6)uSimMarine解析1
  13. mysql的column是什么意思_column意思 数据库中的column是什么意思
  14. 快速掌握验证性因子分析
  15. linux grub2 配置文件,grub2配置文件
  16. 【Spring】SpringBoot 配置 log4j2 日志
  17. Linux硬盘分区相关命令
  18. PVT(Process Voltage Temperature)
  19. Raspberry PI 编译WLan驱动模块, 并配置登录WIFI
  20. word无法创建工作文件,请检查临时环境变量 Mark一下

热门文章

  1. Credit card dataset: SVM Classification --- PCA效果/不平衡数据
  2. @Profile 注解的介绍
  3. LM317,线性稳压电源总结
  4. java实现火车票查询_java抓取12306火车余票信息
  5. 游戏里的角色都什么格式图片_格斗游戏拳皇里的八神庵,为什么在玩家心中人气一直都很高...
  6. gst-rtsp-server 开源包的说明
  7. gst-launch命令转换为C代码(gstreamer框架)
  8. 2020支付宝五福AR图
  9. wav格式怎么转换成mp3
  10. python遗传算法八皇后_python解决八皇后算法详解