diff --git a/src/main/java/top/naccl/dwz/controller/IndexController.java b/src/main/java/top/naccl/dwz/controller/IndexController.java
index f8f1bf5..a1625c6 100644
--- a/src/main/java/top/naccl/dwz/controller/IndexController.java
+++ b/src/main/java/top/naccl/dwz/controller/IndexController.java
@@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -37,11 +38,20 @@ public class IndexController {
 	@ResponseBody
 	public R generateShortURL(@RequestParam String longURL) {
 		if (UrlUtils.checkURL(longURL)) {
-			String shortURL = urlService.saveUrlMap(HashUtils.hashToBase62(longURL), longURL);
+			String shortURL = urlService.saveUrlMap(HashUtils.hashToBase62(longURL), longURL, longURL);
 			return R.ok("请求成功", host + shortURL);
-		} else {
-			return R.create(400, "URL有误");
 		}
+		return R.create(400, "URL有误");
+	}
 
+	@GetMapping("/{shortURL}")
+	public String redirect(@PathVariable String shortURL) {
+		String longURL = urlService.getLongUrlByShortUrl(shortURL);
+		if (longURL != null) {
+			//查询到对应的原始链接,302重定向
+			return "redirect:" + longURL;
+		}
+		//没有对应的原始链接,直接返回首页
+		return "redirect:/";
 	}
 }
diff --git a/src/main/java/top/naccl/dwz/entity/UrlMap.java b/src/main/java/top/naccl/dwz/entity/UrlMap.java
index ba1c266..e138357 100644
--- a/src/main/java/top/naccl/dwz/entity/UrlMap.java
+++ b/src/main/java/top/naccl/dwz/entity/UrlMap.java
@@ -22,9 +22,9 @@ public class UrlMap {
 	private String lurl;//长链接
 	private Date createTime;//创建时间
 
-	public UrlMap(String surl, String lurl, Date createTime) {
+	public UrlMap(String surl, String lurl) {
 		this.surl = surl;
 		this.lurl = lurl;
-		this.createTime = createTime;
+		this.createTime = new Date();
 	}
 }
diff --git a/src/main/java/top/naccl/dwz/service/UrlService.java b/src/main/java/top/naccl/dwz/service/UrlService.java
index 526f3bc..0e3312d 100644
--- a/src/main/java/top/naccl/dwz/service/UrlService.java
+++ b/src/main/java/top/naccl/dwz/service/UrlService.java
@@ -3,5 +3,5 @@ package top.naccl.dwz.service;
 public interface UrlService {
 	String getLongUrlByShortUrl(String shortURL);
 
-	String saveUrlMap(String shortURL, String longURL);
+	String saveUrlMap(String shortURL, String longURL, String originalURL);
 }
diff --git a/src/main/java/top/naccl/dwz/service/impl/UrlServiceImpl.java b/src/main/java/top/naccl/dwz/service/impl/UrlServiceImpl.java
index b56b547..5d38e59 100644
--- a/src/main/java/top/naccl/dwz/service/impl/UrlServiceImpl.java
+++ b/src/main/java/top/naccl/dwz/service/impl/UrlServiceImpl.java
@@ -1,14 +1,17 @@
 package top.naccl.dwz.service.impl;
 
+import cn.hutool.bloomfilter.BitMapBloomFilter;
+import cn.hutool.bloomfilter.BloomFilterUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DuplicateKeyException;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import top.naccl.dwz.entity.UrlMap;
 import top.naccl.dwz.mapper.UrlMapper;
 import top.naccl.dwz.service.UrlService;
 import top.naccl.dwz.util.HashUtils;
 
-import java.util.Date;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @Description: 长短链接映射业务层实现
@@ -19,33 +22,58 @@ import java.util.Date;
 public class UrlServiceImpl implements UrlService {
 	@Autowired
 	UrlMapper urlMapper;
-	private static final String DUPLICATE = " *";
+	@Autowired
+	StringRedisTemplate redisTemplate;
+	//自定义长链接防重复字符串
+	private static final String DUPLICATE = "*";
+	//最近使用的短链接过期时间(分钟)
+	private static final long TIMEOUT = 10;
+	//创建布隆过滤器
+	private static final BitMapBloomFilter FILTER = BloomFilterUtil.createBitMap(10);
 
 	@Override
 	public String getLongUrlByShortUrl(String shortURL) {
-		return urlMapper.getLongUrlByShortUrl(shortURL).replace(DUPLICATE, "");
+		//查找Redis中是否有缓存
+		String longURL = redisTemplate.opsForValue().get(shortURL);
+		if (longURL != null) {
+			//有缓存
+			return longURL;
+		}
+		//Redis没有缓存,从数据库查找
+		return urlMapper.getLongUrlByShortUrl(shortURL);
 	}
 
 	@Override
-	public String saveUrlMap(String shortURL, String longURL) {
+	public String saveUrlMap(String shortURL, String longURL, String originalURL) {
+		//保留长度为1的短链接
+		if (shortURL.length() == 1) {
+			longURL += DUPLICATE;
+			shortURL = saveUrlMap(HashUtils.hashToBase62(longURL), longURL, originalURL);
+		}
 		//在布隆过滤器中查找是否存在
-		if (judgeExist()) {
-			//存在,在长链接后加上指定字符串,重新hash
+		else if (FILTER.contains(shortURL)) {
+			//存在,从Redis中查找是否有缓存
+			String redisLongURL = redisTemplate.opsForValue().get(shortURL);
+			if (redisLongURL != null && originalURL.equals(redisLongURL)) {
+				//Redis有缓存,重置过期时间
+				redisTemplate.expire(shortURL, TIMEOUT, TimeUnit.MINUTES);
+				return shortURL;
+			}
+			//没有缓存,在长链接后加上指定字符串,重新hash
 			longURL += DUPLICATE;
-			shortURL = HashUtils.hashToBase62(longURL);
-			shortURL = saveUrlMap(shortURL, longURL);
-			return shortURL;
+			shortURL = saveUrlMap(HashUtils.hashToBase62(longURL), longURL, originalURL);
 		} else {
 			//不存在,直接存入数据库
 			try {
-				urlMapper.saveUrlMap(new UrlMap(shortURL, longURL, new Date()));
+				urlMapper.saveUrlMap(new UrlMap(shortURL, originalURL));
+				FILTER.add(shortURL);
+				//添加缓存
+				redisTemplate.opsForValue().set(shortURL, originalURL, TIMEOUT, TimeUnit.MINUTES);
 			} catch (Exception e) {
 				if (e instanceof DuplicateKeyException) {
 					//数据库已经存在此短链接,则可能是布隆过滤器误判,在长链接后加上指定字符串,重新hash
 					longURL += DUPLICATE;
-					shortURL = HashUtils.hashToBase62(longURL);
-					shortURL = saveUrlMap(shortURL, longURL);
-					return shortURL;
+					shortURL = saveUrlMap(HashUtils.hashToBase62(longURL), longURL, originalURL);
 				} else {
 					throw e;
 				}
@@ -53,8 +81,4 @@ public class UrlServiceImpl implements UrlService {
 		}
 		return shortURL;
 	}
-
-	public boolean judgeExist() {
-		return false;
-	}
 }