欢迎使用,在本教程中,我们将使用Redis和Springboot来演示URL缩短器(也称为Tiny URL)应用程序。该应用程序将创建原始URL并将其存储在Redis内存缓存中。
1.简介
在继续学习本教程之前,我们将了解一些通用术语,例如Spring Boot,Docker和Redis的简介。
1.1什么是Spring Boot?
- Spring Boot是一个模块,可为Spring框架提供快速的应用程序开发功能,包括自动配置,独立代码和生产就绪代码
- 它创建打包为jar的应用程序,并使用嵌入式servlet容器(例如Tomcat,Jetty或Undertow)直接启动应用程序。因此,无需部署战争文件
- 它通过提供入门模板来简化Maven配置,并有助于解决依赖关系冲突。它会自动识别所需的依赖项并将其导入到应用程序中
- 它有助于删除样板代码,额外的注释和xml配置
- 它提供了强大的批处理功能,并管理其余端点
- 它提供了一个高效的*jpa-starter库,*可以有效地将应用程序与关系数据库连接
- 它提供了微服务架构和云配置,可集中管理所有与应用程序相关的配置属性。
1.2什么是Docker?
在当今世界,Docker是一个重要术语,
- 通常在CI / CD平台中使用,该平台在容器中打包和运行具有其依赖项的应用程序
- 是Linux容器的标准
- 一个集装箱就是一个运行时,在任何Linux内核的运行,并提供一个私人机器般的Linux下的空间
1.2.1 Docker术语
- 图片:Docker容器的表示形式,即Java中的JAR或WAR文件
- 容器:Docker的运行时,即已部署并正在运行的Docker映像。例如,可执行的Spring Boot jar
- 引擎:管理,创建和运行Docker容器的代码
- 中心:公共开发人员注册表,用于分发其代码
- 仓库:与Docker相关的映像的集合,即同一应用程序的不同版本
1.3什么是Redis?
- Redis是用C编程语言编写的开源内存中数据存储
- 提供具有可选持久性的分布式内存中键值数据库
- 通常用作数据库,缓存或消息代理,并支持不同类型的数据库类型,例如字符串,列表,映射,集合或排序集合等。
- 它的速度很快,并且操作本质上是原子的(即两个客户端可以同时访问数据,而Redis服务器将接收更新的值)
- 提供实用程序,例如缓存和消息队列
2. Spring Boot URL缩短器
这是实施本教程的系统指南。
2.1申请先决条件
从本教程开始,我们希望目前的用户已经完成Docker安装。如果有人需要完成Docker安装,请观看此视频。
让我们开始构建应用程序!
3.从Docker Hub提取Redis镜像并启动它
要启动Redis并在localhost环境上工作,我们将从Docker中提取Redis映像并启动容器。用户可以参考以下命令来拉取映像,然后再启动容器。
Docker命令
## Docker commands
## step1 - Pulling redis image from docker hub
docker pull redis
## step2 - Running the container
docker run -d -p 6379:6379 --name my-redis redis
如果一切顺利,则将Docker映像成功从中拉出并成功启动。您可以使用该docker ps -a
命令来验证容器是否已成功启动。
4.创建一个Spring Boot应用程序
以下是开发应用程序涉及的步骤。
4.1 Maven依赖
在这里,我们指定了Spring Boot,Redis,Lombok,Guava和Commons Validator的依赖关系。Maven将自动解决其他依赖关系。该更新文件将具有下面的代码。
pom.xml
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- project properties -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.springboot.redis.tinyurl</groupId>
<artifactId>SpringbootTinyUrl</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<!-- to make the application as fat jar so that spring boot libraries are
included -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.2应用程序属性
在以下位置创建一个新的属性文件:SpringbootTinyUrl/src/main/resources/
并将应用程序和Redis配置添加到该文件。
application.properties
# Application configuration.
## You can change the server port configuration as per their configuration idea.
server.port=10091
# Redis configuration.
## As we are running Redis on Docker we are setting up its configuration.
spring.redis.host=localhost
spring.redis.port=6379
4.3 Java类
让我们编写此应用程序中涉及的所有Java类。
4.3.1实现/主类
将以下代码添加到主类,以从main方法引导应用程序。永远记住,spring boot应用程序的入口点是包含@SpringBootApplication
注释和静态main方法的类。
Runner.java
package com.springboot.redis.tinyurl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Slf4j
@SpringBootApplication
public class Runner {
public static void main(String[] args) {
SpringApplication.run(Runner.class, args);
log.info("Springboot and tinyurl application started successfully.");
}
}
4.3.2模型类
将以下代码添加到模型类。 UrlDto.java
package com.springboot.redis.tinyurl.model;
import com.google.common.hash.Hashing;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
@Getter
@AllArgsConstructor
public class UrlDto {
private final String id;
private final String url;
private final LocalDateTime created;
public static UrlDto create(final String url) {
final String id = Hashing.murmur3_32().hashString(url, StandardCharsets.UTF_8).toString();
return new UrlDto(id, url, LocalDateTime.now());
}
}
4.3.3配置类
将以下代码添加到配置类。默认情况下,Spring Boot是自动配置的,可与字符串基础键/值对Redis模板一起使用。但是,在本教程中,我们将密钥存储为字符串,并将值存储为JSON对象。
RedisConfig.java
package com.springboot.redis.tinyurl.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.springboot.redis.tinyurl.model.UrlDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Autowired
private ObjectMapper objectMapper;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
// Setting up the Redis template object.
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
public RedisTemplate<String, UrlDto> redisTemplate() {
final Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(UrlDto.class);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
final RedisTemplate<String, UrlDto> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
return redisTemplate;
}
}
4.3.4控制器类
将以下代码添加到控制器类,在该类中将使用这些方法创建较短的URL并获取原始URL,以换取较短的URL。 TinyUrlController.java
package com.springboot.redis.tinyurl.controller;
import com.springboot.redis.tinyurl.exception.TinyUrlError;
import com.springboot.redis.tinyurl.model.UrlDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.validator.routines.UrlValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Slf4j
@RestController
@RequestMapping(value = "/rest/url")
public class TinyUrlController {
@Autowired
private RedisTemplate<String, UrlDto> redisTemplate;
@Value("${redis.ttl}")
private long ttl;
@PostMapping
public ResponseEntity create(@RequestBody final String url) {
// Using commons-validator library to validate the input URL.
final UrlValidator urlValidator = new UrlValidator(new String[]{"http", "https"});
if (!urlValidator.isValid(url)) {
// Invalid url return HTTP 400 bad request.
return ResponseEntity.badRequest().body(new TinyUrlError("Invalid URL."));
}
// If valid URL, generate a hash key using guava's murmur3 hashing algorithm.
final UrlDto urlDto = UrlDto.create(url);
log.info("URL id generated = {}", urlDto.getId());
// Store both hasing key and url object in redis.
redisTemplate.opsForValue().set(urlDto.getId(), urlDto, ttl, TimeUnit.SECONDS);
// Return the generated id as a response header.
return ResponseEntity.noContent().header("id", urlDto.getId()).build();
}
@GetMapping(value = "/{id}")
public ResponseEntity getUrl(@PathVariable final String id) {
// Get from redis.
final UrlDto urlDto = redisTemplate.opsForValue().get(id);
if (Objects.isNull(urlDto)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new TinyUrlError("No such key exists."));
} else {
log.info("URL retrieved = {}", urlDto.getUrl());
}
return ResponseEntity.ok(urlDto);
}
}
5.运行应用程序
6.项目演示
打开Postman工具,然后单击以下URL。
// Create short url
http://localhost:10095/rest/url
// Get original url from url id
http://localhost:10095/rest/url/{{urlId}}
7.总结
在本节中,我们了解到:
- Spring Boot,Redis和Docker简介
- 将Redis与Spring Boot应用程序集成以构建URL缩短程序API
- 使用Postman工具创建短网址并获取原始网址