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(); +// } + + + +}