【后端】【Java】可直接落地的 Nginx + Java(Spring Boot)+ Redis 的短链系统实现

一个 示例,包含:

  • 系统架构

  • Nginx 配置

  • Java 代码(短链生成 + 统计 + 302 跳转)

  • Redis 数据结构

  • 访问统计方案

这是一个完整、可部署的模板。


✔️ 1. 系统架构设计

复制代码
用户访问短链 → Nginx → Java短链服务 → Redis查真实链接
                              ↓
                        记录统计数据(异步)
                              ↓
                          302 重定向

✔️ 2. Redis 数据结构设计

1)短链映射

复制代码
Key: short:abcd123
Value: https://example.com/activity?channel=weibo

2)访问统计(可选)

复制代码
短链点击次数:count:abcd123 → incr
访问记录:log:abcd123 → list push {...json...}

✔️ 3. Nginx 配置(负责把短链路由给 Java)

短链域名:https://s.example.com/xxxxxx

nginx.conf

复制代码
server {
    listen 80;
    server_name s.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
    }
}

访问 s.example.com/abcd12 时会转到 Java 后端:

复制代码
GET http://127.0.0.1:8080/abcd12

✔️ 4. Java (Spring Boot) 实现示例

4.1 短链生成 API

Controller

复制代码
@RestController
@RequestMapping("/api")
public class ShortLinkController {

    @Autowired
    private ShortLinkService shortLinkService;

    @PostMapping("/shorten")
    public String createShortLink(@RequestParam String longUrl) {
        return shortLinkService.createShortUrl(longUrl);
    }
}

4.2 Service:短链生成 + 存入 Redis

复制代码
@Service
public class ShortLinkService {

    @Autowired
    private StringRedisTemplate redis;

    private static final String SHORT_KEY_PREFIX = "short:";

    public String createShortUrl(String longUrl) {
        // 生成短链 ID:6 位
        String shortId = RandomStringUtils.randomAlphanumeric(6);

        // 保存到 Redis
        redis.opsForValue().set(SHORT_KEY_PREFIX + shortId, longUrl);

        // 返回短链
        return "https://s.example.com/" + shortId;
    }
}

✔️ 5. Java Controller:接收短链并 302 跳转

关键部分:

  • 查 Redis

  • 记录统计

  • 返回 302

    @RestController
    public class RedirectController {

    复制代码
      @Autowired
      private StringRedisTemplate redis;
    
      @Autowired
      private AsyncLogService asyncLogService;
    
      private static final String SHORT_KEY_PREFIX = "short:";
    
      @GetMapping("/{shortId}")
      public ResponseEntity<Void> redirect(@PathVariable String shortId,
                                           HttpServletRequest request) {
          String key = SHORT_KEY_PREFIX + shortId;
          String longUrl = redis.opsForValue().get(key);
    
          if (longUrl == null) {
              return ResponseEntity.notFound().build();
          }
    
          // 异步记录访问
          asyncLogService.log(shortId, request);
    
          // 302 跳转
          HttpHeaders headers = new HttpHeaders();
          headers.setLocation(URI.create(longUrl));
          return new ResponseEntity<>(headers, HttpStatus.FOUND);
      }

    }


✔️ 6. 异步记录统计(可选)

通过 @Async 保存访问日志,不阻塞跳转。

异步记录点击数量 + 访问日志

复制代码
@Service
public class AsyncLogService {

    @Autowired
    private StringRedisTemplate redis;

    @Async
    public void log(String shortId, HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        String ip = request.getRemoteAddr();
        long timestamp = System.currentTimeMillis() / 1000;

        // 点击次数
        redis.opsForValue().increment("count:" + shortId);

        // 访问日志
        JSONObject log = new JSONObject();
        log.put("ip", ip);
        log.put("ua", ua);
        log.put("time", timestamp);

        redis.opsForList().leftPush("log:" + shortId, log.toString());
    }
}

✔️ 7. 查询统计的 API 示例

查询访问次数

复制代码
@GetMapping("/api/count/{shortId}")
public Long getCount(@PathVariable String shortId) {
    return Long.valueOf(redis.opsForValue().get("count:" + shortId));
}

查询访问日志

复制代码
@GetMapping("/api/logs/{shortId}")
public List<String> getLogs(@PathVariable String shortId) {
    return redis.opsForList().range("log:" + shortId, 0, 100);
}

✔️ 8. 运行效果

  1. 创建短链:

    POST /api/shorten
    longUrl=https://example.com/page?channel=test

    返回:
    https://s.example.com/aB92kF

  2. 用户访问短链:

    GET https://s.example.com/aB92kF

  3. Java 读取 Redis → 记录统计 → 302 跳转

  4. 在后台看到统计数据:

    count:aB92kF = 1023
    log:aB92kF = [ {ip:..., ua:..., time:...}, ... ]


相关推荐
独断万古他化6 分钟前
【SSM开发实战:博客系统】(三)核心业务功能开发与安全加密实现
spring boot·spring·mybatis·博客系统·加密
rannn_11123 分钟前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
qq_124987075326 分钟前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
短剑重铸之日33 分钟前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
若鱼19191 小时前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
倒流时光三十年1 小时前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
觉醒大王1 小时前
强女思维:着急,是贪欲外显的相。
java·论文阅读·笔记·深度学习·学习·自然语言处理·学习方法
努力学编程呀(๑•ี_เ•ี๑)1 小时前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea
全栈工程师修炼指南1 小时前
Nginx | stream 四层反向代理:SSL、PREREAD 阶段模块指令浅析与实践
运维·网络·网络协议·nginx·ssl
码农小卡拉1 小时前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot