Java实现长链接转成短链接

  • 前言: 在app内分享链接到微信,会出现链接太长的情况,写了个工具类将长链接转成短链接
  • 原理:
    1. 通过redis的原子递增作为计数器
    2. 将十进制转成62进制缩短链接
    3. redis存储长链接和短链接的映射关系
@RequiredArgsConstructor
@Component
public class LongLinkToShortUtil {

    private final RedisTemplate<String,String> redisTemplate;

    private static final String SHORT_URL_KEY = "SHORT_URL_KEY";
    private static final String LOCALHOST = "http://localhost:8080/";
    private static final String SHORT_LONG_PREFIX = "short_long_prefix_";
    private static final String CACHE_KEY_PREFIX = "cache_key_prefix_";
    final static char[] charSet = {'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', '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'
    };

    public String getShortUrl(String longUrl) {
        // 通过长链接获取短链接
        String cache = redisTemplate.opsForValue().get(CACHE_KEY_PREFIX + longUrl);
        if (cache != null) {
            return LOCALHOST + hex10To62(Long.valueOf(cache));
        }
        // 获取计数器
        Long num = redisTemplate.opsForValue().increment(SHORT_URL_KEY);
        // 转换成短字符
        String shortStr = hex10To62(num);
        // 同时存储长链接和短链接的映射关系
        redisTemplate.opsForValue().set(SHORT_LONG_PREFIX + shortStr, longUrl);
        redisTemplate.opsForValue().set(CACHE_KEY_PREFIX + longUrl, shortStr, 60 * 60, TimeUnit.SECONDS);
        return LOCALHOST + shortStr;
    }


    /**
     * 10进制转62进制
     */
    public String hex10To62(Long number){
        Long rest=number;
        Stack<Character> stack=new Stack<>();
        StringBuilder result=new StringBuilder(0);
        while(rest!=0){
            stack.add(charSet[new Long((rest-(rest/62)*62)).intValue()]);
            rest=rest/62;
        }
        while (!stack.isEmpty()) {
            result.append(stack.pop());
        }
        return result.toString();
    }




}

Netty支持连接和连接,具体采用哪种方式取决于你的应用场景和需求。下面是Java代码实现连接和连接的示例: 1. 连接 ```java public class LongConnectionServer { public static void main(String[] args) { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new LongConnectionHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); ChannelFuture f = b.bind(8080).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } } public class LongConnectionHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 处理请求 // ... // 返回响应 ByteBuf resp = Unpooled.copiedBuffer("Hello World".getBytes()); ctx.write(resp); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } } ``` 2. 连接 ```java public class ShortConnectionServer { public static void main(String[] args) { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ShortConnectionHandler()); } }); ChannelFuture f = b.connect("localhost", 8080).sync(); // 发送请求 ByteBuf req = Unpooled.copiedBuffer("Hello Server".getBytes()); f.channel().writeAndFlush(req); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } } public class ShortConnectionHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf resp = (ByteBuf) msg; byte[] bytes = new byte[resp.readableBytes()]; resp.readBytes(bytes); String respStr = new String(bytes); System.out.println("Server response: " + respStr); ctx.close(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } } ``` 以上示例中,LongConnectionServer和LongConnectionHandler实现连接的服务端和处理器,ShortConnectionServer和ShortConnectionHandler实现连接的客户端和处理器。需要注意的是,连接需要使用SO_KEEPALIVE选项来保持连接,连接则不需要。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值