From 00e9949550db91c9a032531a815599a32601dd64 Mon Sep 17 00:00:00 2001
From: TheEnd <1302344380@qq.com>
Date: Sun, 31 Jul 2022 19:35:26 +0800
Subject: [PATCH] =?UTF-8?q?RedisShortUrlStore=20=E5=AE=8C=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 8 ++++
.../starter/ShortUrlAutoConfiguration.java | 17 ++++++++-
zy-shorturl-store/pom.xml | 12 ++++++
.../java/cn/shorturl/store/ShortUrlStore.java | 17 +++++++--
.../store/exception/HashAlreadyException.java | 17 +++++++++
.../store/store/JdbcShortUrlStore.java | 9 +++++
.../store/store/RedisShortUrlStore.java | 34 +++++++++++++++--
.../store/template/DefaultRedisTemplate.java | 32 ++++++++++++++++
.../store/template/ShortUrlRedisTemplate.java | 38 +++++++++++++++++++
9 files changed, 176 insertions(+), 8 deletions(-)
create mode 100644 zy-shorturl-store/src/main/java/cn/shorturl/store/exception/HashAlreadyException.java
create mode 100644 zy-shorturl-store/src/main/java/cn/shorturl/store/template/DefaultRedisTemplate.java
create mode 100644 zy-shorturl-store/src/main/java/cn/shorturl/store/template/ShortUrlRedisTemplate.java
diff --git a/pom.xml b/pom.xml
index 8e2b4db..eb1794a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,4 +27,12 @@
UTF-8
+
+
+ org.springframework.data
+ spring-data-redis
+ true
+
+
+
\ No newline at end of file
diff --git a/zy-shorturl-spring-boot-starter/src/main/java/cn/shorturl/boot/starter/ShortUrlAutoConfiguration.java b/zy-shorturl-spring-boot-starter/src/main/java/cn/shorturl/boot/starter/ShortUrlAutoConfiguration.java
index 7db6471..fe06697 100644
--- a/zy-shorturl-spring-boot-starter/src/main/java/cn/shorturl/boot/starter/ShortUrlAutoConfiguration.java
+++ b/zy-shorturl-spring-boot-starter/src/main/java/cn/shorturl/boot/starter/ShortUrlAutoConfiguration.java
@@ -3,7 +3,9 @@ package cn.shorturl.boot.starter;
import cn.shorturl.core.ShortUrlConfig;
import cn.shorturl.core.ShortUrlUtil;
import cn.shorturl.store.ShortUrlStore;
+import cn.shorturl.store.store.JdbcShortUrlStore;
import cn.shorturl.store.store.RedisShortUrlStore;
+import cn.shorturl.store.template.ShortUrlRedisTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -13,6 +15,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.StringRedisTemplate;
import javax.annotation.PostConstruct;
@@ -44,9 +48,18 @@ public class ShortUrlAutoConfiguration {
@ConditionalOnMissingBean(ShortUrlStore.class)
@ConditionalOnBean(ShortUrlUtil.class)
@ConditionalOnProperty(prefix = "shorturl.store", name = "store-type", havingValue = "redis")
- public ShortUrlStore redisShortUrlStore(ShortUrlUtil util) {
+ public ShortUrlStore redisShortUrlStore(ShortUrlUtil util, RedisConnectionFactory connectionFactory) {
log.info("use short-url store: {}", RedisShortUrlStore.class.getName());
- return new RedisShortUrlStore(util);
+ return new RedisShortUrlStore(util, new ShortUrlRedisTemplate(connectionFactory));
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(ShortUrlStore.class)
+ @ConditionalOnBean(ShortUrlUtil.class)
+ @ConditionalOnProperty(prefix = "shorturl.store", name = "store-type", havingValue = "jdbc")
+ public ShortUrlStore jdbcShortUrlStore(ShortUrlUtil util) {
+ log.info("use short-url store: {}", RedisShortUrlStore.class.getName());
+ return new JdbcShortUrlStore(util);
}
}
diff --git a/zy-shorturl-store/pom.xml b/zy-shorturl-store/pom.xml
index ae03c0e..e2e6b7d 100644
--- a/zy-shorturl-store/pom.xml
+++ b/zy-shorturl-store/pom.xml
@@ -23,6 +23,18 @@
zy-short-url-core
1.0-SNAPSHOT
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+
\ No newline at end of file
diff --git a/zy-shorturl-store/src/main/java/cn/shorturl/store/ShortUrlStore.java b/zy-shorturl-store/src/main/java/cn/shorturl/store/ShortUrlStore.java
index a3a83c2..bb69a6c 100644
--- a/zy-shorturl-store/src/main/java/cn/shorturl/store/ShortUrlStore.java
+++ b/zy-shorturl-store/src/main/java/cn/shorturl/store/ShortUrlStore.java
@@ -1,7 +1,6 @@
package cn.shorturl.store;
import cn.shorturl.core.ShortUrl;
-import cn.shorturl.core.ShortUrlConfig;
import cn.shorturl.core.ShortUrlUtil;
import java.util.Date;
@@ -30,12 +29,16 @@ public abstract class ShortUrlStore {
*/
public ShortUrl add(String url, Date expireTime) {
Integer max = util.getConfig().getRetryMax();
- if (max == null) {
- max = 5;
+ if (max == null || max < 1) {
+ max = 10;
}
ShortUrl shortUrl = new ShortUrl().setUrl(url).setGmtExpire(expireTime).setGmtCreate(new Date());
for (int i = 0; i < max; i++) {
String hash = hash(url);
+ if (contains(hash)) {
+ url += (int) (Math.random() * 10);
+ continue;
+ }
try {
shortUrl.setHash(hash);
add(shortUrl);
@@ -50,6 +53,7 @@ public abstract class ShortUrlStore {
/**
* 添加短链接(内部访问, 请勿外部访问)
* @param shortUrl 短链接
+ * @return 短链接
*/
protected abstract ShortUrl add(ShortUrl shortUrl);
@@ -60,6 +64,13 @@ public abstract class ShortUrlStore {
*/
public abstract ShortUrl get(String hash);
+ /**
+ * Hash是否已经存在
+ * @param hash Hash
+ * @return 是否已经存在
+ */
+ public abstract boolean contains(String hash);
+
/**
* 对URL进行Hash编码
* @param url 原链接
diff --git a/zy-shorturl-store/src/main/java/cn/shorturl/store/exception/HashAlreadyException.java b/zy-shorturl-store/src/main/java/cn/shorturl/store/exception/HashAlreadyException.java
new file mode 100644
index 0000000..fcbb327
--- /dev/null
+++ b/zy-shorturl-store/src/main/java/cn/shorturl/store/exception/HashAlreadyException.java
@@ -0,0 +1,17 @@
+package cn.shorturl.store.exception;
+
+/**
+ * @author ZhuoQinghui
+ * @version 1.0.0
+ * Create By 2022/7/31 18:49
+ */
+public class HashAlreadyException extends RuntimeException {
+
+ public HashAlreadyException() {
+ }
+
+ public HashAlreadyException(String message) {
+ super(message);
+ }
+
+}
diff --git a/zy-shorturl-store/src/main/java/cn/shorturl/store/store/JdbcShortUrlStore.java b/zy-shorturl-store/src/main/java/cn/shorturl/store/store/JdbcShortUrlStore.java
index d8a8749..57e9321 100644
--- a/zy-shorturl-store/src/main/java/cn/shorturl/store/store/JdbcShortUrlStore.java
+++ b/zy-shorturl-store/src/main/java/cn/shorturl/store/store/JdbcShortUrlStore.java
@@ -1,6 +1,7 @@
package cn.shorturl.store.store;
import cn.shorturl.core.ShortUrl;
+import cn.shorturl.core.ShortUrlUtil;
import cn.shorturl.store.ShortUrlStore;
/**
@@ -8,6 +9,9 @@ import cn.shorturl.store.ShortUrlStore;
*/
public class JdbcShortUrlStore extends ShortUrlStore {
+ public JdbcShortUrlStore(ShortUrlUtil util) {
+ super.util = util;
+ }
@Override
protected ShortUrl add(ShortUrl shortUrl) {
@@ -19,4 +23,9 @@ public class JdbcShortUrlStore extends ShortUrlStore {
return null;
}
+ @Override
+ public boolean contains(String hash) {
+ return false;
+ }
+
}
diff --git a/zy-shorturl-store/src/main/java/cn/shorturl/store/store/RedisShortUrlStore.java b/zy-shorturl-store/src/main/java/cn/shorturl/store/store/RedisShortUrlStore.java
index 34ad253..1eaa352 100644
--- a/zy-shorturl-store/src/main/java/cn/shorturl/store/store/RedisShortUrlStore.java
+++ b/zy-shorturl-store/src/main/java/cn/shorturl/store/store/RedisShortUrlStore.java
@@ -3,27 +3,55 @@ package cn.shorturl.store.store;
import cn.shorturl.core.ShortUrl;
import cn.shorturl.core.ShortUrlUtil;
import cn.shorturl.store.ShortUrlStore;
+import cn.shorturl.store.exception.HashAlreadyException;
+import cn.shorturl.store.template.ShortUrlRedisTemplate;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
/**
* @author Lenovo
*/
public class RedisShortUrlStore extends ShortUrlStore {
+ ShortUrlRedisTemplate redisTemplate;
+ public static final String SHORT_KEY = "short:url:";
- public RedisShortUrlStore(ShortUrlUtil util) {
+ public RedisShortUrlStore(ShortUrlUtil util, ShortUrlRedisTemplate redisTemplate) {
super.util = util;
+ this.redisTemplate = redisTemplate;
}
@Override
protected ShortUrl add(ShortUrl shortUrl) {
System.out.println(shortUrl);
- return null;
+ String key = SHORT_KEY + shortUrl.getHash();
+ Date expire = shortUrl.getGmtExpire();
+ Boolean save;
+ if (expire != null) {
+ long time = expire.getTime() - System.currentTimeMillis();
+ if (time < 0) {
+ return null;
+ }
+ save = redisTemplate.opsForValue().setIfAbsent(key, shortUrl, time, TimeUnit.MILLISECONDS);
+ } else {
+ save = redisTemplate.opsForValue().setIfAbsent(key, shortUrl);
+ }
+ if (!Boolean.TRUE.equals(save)) {
+ throw new HashAlreadyException("hash already exists");
+ }
+ return shortUrl;
}
@Override
public ShortUrl get(String hash) {
- return null;
+ return redisTemplate.opsForValue().get(SHORT_KEY + hash);
+ }
+
+ @Override
+ public boolean contains(String hash) {
+ return redisTemplate.opsForValue().get(SHORT_KEY + hash) != null;
}
}
diff --git a/zy-shorturl-store/src/main/java/cn/shorturl/store/template/DefaultRedisTemplate.java b/zy-shorturl-store/src/main/java/cn/shorturl/store/template/DefaultRedisTemplate.java
new file mode 100644
index 0000000..5827e3a
--- /dev/null
+++ b/zy-shorturl-store/src/main/java/cn/shorturl/store/template/DefaultRedisTemplate.java
@@ -0,0 +1,32 @@
+package cn.shorturl.store.template;
+
+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.RedisSerializer;
+
+/**
+ * @author ZhuoQinghui
+ * @version 1.0.0
+ * Create By 2022/7/31 18:07
+ */
+public class DefaultRedisTemplate extends RedisTemplate {
+ public DefaultRedisTemplate(Class kClass, Class vClass) {
+ if (kClass.equals(String.class)) {
+ this.setKeySerializer(RedisSerializer.string());
+ this.setHashKeySerializer(RedisSerializer.string());
+ } else {
+ this.setKeySerializer(new Jackson2JsonRedisSerializer<>(kClass));
+ this.setHashKeySerializer(new Jackson2JsonRedisSerializer<>(kClass));
+ }
+ this.setValueSerializer(new Jackson2JsonRedisSerializer<>(vClass));
+ this.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(vClass));
+ }
+
+ public DefaultRedisTemplate(Class kClass, Class vClass, RedisConnectionFactory connectionFactory) {
+ this(kClass, vClass);
+ this.setConnectionFactory(connectionFactory);
+ this.afterPropertiesSet();
+ }
+
+}
diff --git a/zy-shorturl-store/src/main/java/cn/shorturl/store/template/ShortUrlRedisTemplate.java b/zy-shorturl-store/src/main/java/cn/shorturl/store/template/ShortUrlRedisTemplate.java
new file mode 100644
index 0000000..be4d92a
--- /dev/null
+++ b/zy-shorturl-store/src/main/java/cn/shorturl/store/template/ShortUrlRedisTemplate.java
@@ -0,0 +1,38 @@
+package cn.shorturl.store.template;
+
+import cn.shorturl.core.ShortUrl;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+
+/**
+ * @author ZhuoQinghui
+ * @version 1.0.0
+ * Create By 2022/7/31 18:03
+ */
+public class ShortUrlRedisTemplate extends DefaultRedisTemplate {
+
+ public ShortUrlRedisTemplate() {
+ super(String.class, ShortUrl.class);
+ }
+
+ public ShortUrlRedisTemplate(RedisConnectionFactory connectionFactory) {
+ this();
+ this.setConnectionFactory(connectionFactory);
+ this.afterPropertiesSet();
+ }
+
+// public ShortUrlRedisTemplate() {
+// this.setKeySerializer(RedisSerializer.string());
+// this.setHashKeySerializer(RedisSerializer.string());
+// this.setValueSerializer(new Jackson2JsonRedisSerializer<>(ShortUrl.class));
+// this.setHashValueSerializer(RedisSerializer.string());
+// }
+//
+// public ShortUrlRedisTemplate(RedisConnectionFactory connectionFactory) {
+// this();
+// this.setConnectionFactory(connectionFactory);
+// this.afterPropertiesSet();
+// }
+
+
+
+}