【后端】【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:...}, ... ]


相关推荐
廋到被风吹走2 小时前
【Spring】对多线程的支持
java·后端·spring
pyniu2 小时前
redis day1
java·前端·spring
dzl843942 小时前
2025年技术栈备忘
java
lynnlovemin2 小时前
从暴力到高效:C++ 算法优化实战 —— 排序与双指针篇
java·c++·算法
BD_Marathon2 小时前
【JavaWeb】Tomcat_WebAPP的标准结构
java·tomcat·web app
Q_Q5110082852 小时前
python+springboot+django/flask基于深度学习的音乐推荐系统
spring boot·python·django·flask·node.js·php
Q_Q5110082852 小时前
python+springboot+django/flask基于深度学习的淘宝用户购物可视化与行为预测系统
spring boot·python·django·flask·node.js·php
小雨下雨的雨2 小时前
第8篇:Redis缓存设计与缓存问题
java·redis·缓存
TT哇3 小时前
【@NotBlank】@NotBlank与@NotEmpty与@NotNull区别
java·开发语言