RedisShortUrlStore 完成
This commit is contained in:
		
							parent
							
								
									7ce692a2b2
								
							
						
					
					
						commit
						00e9949550
					
				
							
								
								
									
										8
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								pom.xml
									
									
									
									
									
								
							|  | @ -27,4 +27,12 @@ | |||
|         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
|     </properties> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.data</groupId> | ||||
|             <artifactId>spring-data-redis</artifactId> | ||||
|             <optional>true</optional> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
| </project> | ||||
|  | @ -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); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -23,6 +23,18 @@ | |||
|             <artifactId>zy-short-url-core</artifactId> | ||||
|             <version>1.0-SNAPSHOT</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.fasterxml.jackson.core</groupId> | ||||
|             <artifactId>jackson-core</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.fasterxml.jackson.core</groupId> | ||||
|             <artifactId>jackson-databind</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>com.fasterxml.jackson.core</groupId> | ||||
|             <artifactId>jackson-annotations</artifactId> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
| </project> | ||||
|  | @ -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 原链接 | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -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; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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); | ||||
|         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; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -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<K, V> extends RedisTemplate<K, V> { | ||||
|     public DefaultRedisTemplate(Class<K> kClass, Class<V> 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<K> kClass, Class<V> vClass, RedisConnectionFactory connectionFactory) { | ||||
|         this(kClass, vClass); | ||||
|         this.setConnectionFactory(connectionFactory); | ||||
|         this.afterPropertiesSet(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -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<String, ShortUrl> { | ||||
| 
 | ||||
|     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(); | ||||
| //    } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user