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


相关推荐
郑州光合科技余经理12 分钟前
出海外卖平台:支付对接为什么要和下单收款分开
android·java·开发语言·前端·后端·php·ai编程
我是人✓19 分钟前
Spring框架的事务管理
java·后端·spring
javachen__32 分钟前
JsonView:一套VO实现多角色字段返回
java·linux·服务器
高级程序源42 分钟前
hive电商平台商品销售数据分析与趋势预测45659-计算机课程设计、毕业设计
vue.js·hive·spring boot·mysql·数据分析·django·课程设计
行者-全栈开发1 小时前
SpringBoot 生产环境踩坑实录:10个真实故障案例与教训
java·spring boot·后端
李福春1 小时前
斗破Google ADK Java苍穹-第7境斗皇-御天地-Harness治理
java·人工智能·python·深圳同盟·腾讯云架构师技术同盟·adk java·harness 治理
Wang's Blog1 小时前
Java 项目部署之 Docker工具快速入门: 容器命令练习:创建、改文件、重启到删除的完整闭环
java·开发语言·docker
我是人✓1 小时前
Java面向对象核心特性深度解析
java·前端·算法
Wx-bishekaifayuan1 小时前
springboot线上中医药养生平台管理系统36753-计算机课程设计、毕业设计
java·spring boot·后端·spring·课程设计·express·旅游
Wx-bishekaifayuan1 小时前
springboot大学生就业平台47691-计算机课程设计、毕业设计
java·spring boot·后端·elasticsearch·课程设计·express·旅游