在springboot中缩短一个url链接

码农老张 后端 最近

在springboot中缩短一个url链接

缩短 URL 是现代应用程序中常见的需求,通常用于减少长 URL 的长度,使其更易于分享。URL 缩短服务的核心思路是将长 URL 映射到一个唯一的短代码。较为复杂的场景可能涉及多种功能,例如:

  1. 缩短的 URL 自动过期(即在一定时间后失效)。
  2. 统计 URL 的访问量。
  3. 检查并避免短 URL 重复。
  4. 添加安全机制,如防止恶意链接。

场景案例

我们可以设计一个场景:

  1. 用户通过 API 提交长 URL。
  2. 系统生成短 URL,短 URL 有有效期(例如 7 天),并存储在数据库中。
  3. 用户可以通过 API 查询短 URL 的访问次数。
  4. 每当有人访问短 URL,系统会记录访问量,并自动重定向到原始的长 URL。
  5. 在短 URL 过期后,无法再进行重定向。

技术栈

  1. Spring Boot: 用于快速构建 RESTful API 服务。
  2. H2 数据库: 用于存储 URL 和相关元数据。
  3. Java UUID: 生成唯一短码。
  4. Java 定时任务: 自动清理过期 URL。

Step 1: 项目结构css

代码解读
复制代码
src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ ├── UrlShortenerApplication.java │ │ ├── controller/ │ │ │ └── UrlController.java │ │ ├── model/ │ │ │ └── Url.java │ │ ├── repository/ │ │ │ └── UrlRepository.java │ │ └── service/ │ │ └── UrlService.java │ └── resources/ │ └── application.properties

Step 2: 创建实体类 Url

Url.java 是用于存储长 URL、短 URL 以及相关元数据的实体类。java

代码解读
复制代码
package com.example.model; import javax.persistence.*; import java.time.LocalDateTime; @Entity public class Url { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String originalUrl; private String shortCode; private LocalDateTime createdAt; private LocalDateTime expiresAt; private int visitCount; public Url() {} public Url(String originalUrl, String shortCode, LocalDateTime createdAt, LocalDateTime expiresAt) { this.originalUrl = originalUrl; this.shortCode = shortCode; this.createdAt = createdAt; this.expiresAt = expiresAt; this.visitCount = 0; } // getters and setters }

Step 3: 创建 Repository 接口

使用 Spring Data JPA,我们可以快速创建一个操作数据库的接口。java

代码解读
复制代码
package com.example.repository; import com.example.model.Url; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface UrlRepository extends JpaRepository<Url, Long> { Optional<Url> findByShortCode(String shortCode); void deleteByExpiresAtBefore(LocalDateTime dateTime); }

Step 4: 编写服务类 UrlService

UrlService.java 包含业务逻辑,例如生成短 URL、处理 URL 重定向、统计访问量等。java

代码解读
复制代码
package com.example.service; import com.example.model.Url; import com.example.repository.UrlRepository; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.Optional; import java.util.UUID; @Service public class UrlService { private final UrlRepository urlRepository; public UrlService(UrlRepository urlRepository) { this.urlRepository = urlRepository; } public String shortenUrl(String originalUrl, int expirationDays) { String shortCode = UUID.randomUUID().toString().substring(0, 8); // 生成短码 LocalDateTime createdAt = LocalDateTime.now(); LocalDateTime expiresAt = createdAt.plusDays(expirationDays); Url url = new Url(originalUrl, shortCode, createdAt, expiresAt); urlRepository.save(url); return shortCode; } public Optional<Url> getOriginalUrl(String shortCode) { Optional<Url> urlOptional = urlRepository.findByShortCode(shortCode); urlOptional.ifPresent(url -> { if (url.getExpiresAt().isAfter(LocalDateTime.now())) { url.setVisitCount(url.getVisitCount() + 1); urlRepository.save(url); } }); return urlOptional.filter(url -> url.getExpiresAt().isAfter(LocalDateTime.now())); } public int getVisitCount(String shortCode) { return urlRepository.findByShortCode(shortCode) .map(Url::getVisitCount) .orElse(0); } // 定时任务清理过期 URL public void cleanUpExpiredUrls() { urlRepository.deleteByExpiresAtBefore(LocalDateTime.now()); } }

Step 5: 编写 Controller

UrlController.java 是与前端或其他客户端交互的层。java

代码解读
复制代码
package com.example.controller; import com.example.model.Url; import com.example.service.UrlService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.Optional; @RestController @RequestMapping("/api/url") public class UrlController { private final UrlService urlService; public UrlController(UrlService urlService) { this.urlService = urlService; } @PostMapping("/shorten") public ResponseEntity<String> shortenUrl(@RequestParam String originalUrl, @RequestParam(defaultValue = "7") int expirationDays) { String shortCode = urlService.shortenUrl(originalUrl, expirationDays); return ResponseEntity.ok("Shortened URL: http://localhost:8080/api/url/" + shortCode); } @GetMapping("/{shortCode}") public ResponseEntity<?> redirectUrl(@PathVariable String shortCode) { Optional<Url> urlOptional = urlService.getOriginalUrl(shortCode); return urlOptional .map(url -> ResponseEntity.status(302).header("Location", url.getOriginalUrl()).build()) .orElse(ResponseEntity.notFound().build()); } @GetMapping("/{shortCode}/stats") public ResponseEntity<Integer> getUrlStats(@PathVariable String shortCode) { int visitCount = urlService.getVisitCount(shortCode); return ResponseEntity.ok(visitCount); } }

Step 6: 定时清理任务

Spring Boot 可以通过 @Scheduled 注解定期执行任务。我们可以创建一个任务来清理过期的 URL。java

代码解读
复制代码
package com.example.service; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class CleanupTask { private final UrlService urlService; public CleanupTask(UrlService urlService) { this.urlService = urlService; } @Scheduled(cron = "0 0 0 * * ?") // 每天午夜执行一次 public void cleanExpiredUrls() { urlService.cleanUpExpiredUrls(); } }

Step 7: 配置文件

application.properties 中配置 H2 数据库以及其他 Spring Boot 配置。properties

代码解读
复制代码
spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.h2.console.enabled=true spring.jpa.hibernate.ddl-auto=update

Step 8: 启动类 UrlShortenerApplication.javajava

代码解读
复制代码
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class UrlShortenerApplication { public static void main(String[] args) { SpringApplication.run(UrlShortenerApplication.class, args); } }

运行服务

  1. 使用 POST 请求 /api/url/shorten 提交长 URL 并获取短 URL。
  2. 使用 GET 请求 /api/url/{shortCode} 重定向到原始 URL。
  3. 使用 GET 请求 /api/url/{shortCode}/stats 获取短 URL 的访问量。
  4. 每天定时任务会清理过期的 URL。

总结

通过 Spring Boot 框架,我们可以快速构建一个带有定时任务、访问统计以及过期处理的 URL 缩短服务。在真实场景中,可能还会涉及更多的功能,如用户身份验证、URL 黑名单过滤等。

转载来源:https://juejin.cn/post/7414321375550783514

Apipost 私有化火热进行中

评论