一 單點登陸

代碼如下
package com.jt.demos;
import redis.clients.jedis.Jedis;
import java.util.UUID;
/**
* 單點登錄應用實踐
*/
public class SSODemo01 {
static String token;
//模仿訪問服務端的資源
static void doGetResource(){
//1.檢查token是否存在,(token是存盤在客戶端-Cookie,localStorage)
if(token==null){
System.out.println("please login");
return;
}
//2.檢查token是否已經失效
Jedis jedis=new Jedis("192.168.126.130",6379);
String user = jedis.get(token);
jedis.close();
if(user==null){
System.out.println("login timeout or token invalid");
return;
}
//3.回傳你要訪問的資源
System.out.println("return user resource");
}
static void doLogin(String username,String password){
if("jack".equals(username)&&"123456".equals(password)){
System.out.println("login ok");
String token= UUID.randomUUID().toString();
Jedis jedis=new Jedis("192.168.126.130",6379);
jedis.set(token,username);//存盤用戶資訊
jedis.expire(token,1);
jedis.close();
//將token存盤到客戶端
SSODemo01.token=token;
return;
}
System.out.println("username or password error");
}
public static void main(String[] args) throws InterruptedException {//這里的main方法代表客戶端
//1.訪問資源
doGetResource();
//2.執行登錄操作
doLogin("jack","123456");
//3.再次訪問資源
Thread.sleep(1000);
doGetResource();
}
}
二 驗證碼實作:
package com.jt.demos;
import redis.clients.jedis.Jedis;
/**登錄驗證碼實踐
* 1)進入登錄頁面之前先創建一個驗證碼,并將其存盤在redis中
* 2)登錄時輸入驗證碼,并且將驗證碼與redis中的驗證碼進行比對
* */
public class CodeDemo01 {
static void doLogin(String username,String password,String inputCode){
//1.校驗驗證碼
//1.1驗證是否為空
if(inputCode==null||"".equals(inputCode)){
System.out.println("please input code");
return;
}
//1.2驗證redis中的code
Jedis jedis=new Jedis("192.168.126.130",6379);
String dbCode=jedis.get("code");
if(dbCode==null){
System.out.println("code timeout");
return;
}
if(!inputCode.equals(dbCode)){
System.out.println("code error");
return;
}
//2......
System.out.println("繼續驗證用戶身份合法性");
}
public static void main(String[] args) {
char[] chars={
'A','B','C','D','1','2','.'
};//后續可以寫一個演算法從這個陣列中隨機取出四個值
//1.生成一個隨機驗證碼
String code="12AB";
Jedis jedis=new Jedis("192.168.126.130",6379);
jedis.set("code","12AB");
jedis.expire("code",60);
jedis.close();
//2.執行登錄操作
doLogin("jack","123456","12AB");
}
}
三 投票系統

代碼:
package com.jt.demos;
import redis.clients.jedis.Jedis;
import java.util.Set;
/**
* 設計一個基于某個活動的投票系統.
*/
public class VoteDemo01 {
//注意,將來這個連接不能多執行緒共享
private static Jedis jedis=new Jedis("192.168.126.130",6379);
/**
* 判定userId是否參與過activityId這個活動的投票
* @param activityId
* @param userId
* @return true表示參與過投票
*/
static boolean checkVote(String activityId,String userId){
//判斷set集合activityId對應的值中是否包含這個userId
return jedis.sismember(activityId,userId);
}
/**
* 執行投票邏輯
* @param activityId
* @param userId
* @return true 表示投票ok
*/
static boolean addVote(String activityId,String userId){
if(checkVote(activityId,userId)){
System.out.println("您已經參與過這個投票");
return false;
}
jedis.sadd(activityId,userId);
return true;
}
/**
* 獲取活動的總票數
* @param activityId
* @return
*/
static Long getActivityVotes(String activityId){
return jedis.scard(activityId);
}
/**
* 獲取參與了投票的用戶id
* @param activityId
* @return
*/
static Set<String> getActivityUsers(String activityId){
return jedis.smembers(activityId);
}
public static void main(String[] args) {
//1.設定一個活動
//1)獲取id
String activityId="10001";
//2)活動標題
//3)活動內容
//2.基于活動進行投票設計
String user1="201";
String user2="202";
String user3="203";
//2.1 一個用戶對同一個活動不能重復投票
//boolean flag=checkVote(activityId,user1);
//System.out.println("flag="+flag);
//2.2 執行投票
addVote(activityId,user1);
addVote(activityId,user2);
addVote(activityId,user3);
//2.3 能夠顯示參與投票的人數
long voteCount=getActivityVotes(activityId);
System.out.println(voteCount);
//2.4 管理員可以查看哪些人參與了投票
Set<String> userIds=getActivityUsers(activityId);
System.out.println(userIds);
}
}
四 秒殺佇列

代碼如下
package com.jt.demos;
import redis.clients.jedis.Jedis;
//秒殺佇列演示
//描述邏輯中會將商品搶購資訊先寫到redis(以佇列形式進行存盤),
//因為寫redis記憶體資料庫要比寫你的mysql資料庫快很多倍
//演算法:先進先出(FIFO)-體現公平性
public class SecondKillDemo01 {
//商品搶購首先是入隊
static void enque(String msg){//入隊
Jedis jedis=new Jedis("192.168.126.130",6379);
jedis.auth("123456");//沒有認證不需要寫這個陳述句
jedis.lpush("queue",msg);
jedis.close();
}
//底層異步出隊(基于這個訊息,生成訂單,扣減庫存,...)
static String deque(){//出隊
Jedis jedis=new Jedis("192.168.126.130",6379);
jedis.auth("123456");//沒有認證不需要寫這個陳述句
String result=jedis.rpop("queue");
jedis.close();
return result;
}
public static void main(String[] args){
//1.多次搶購(模擬在界面上多次點擊操作)
new Thread(){
@Override
public void run() {
for(int i=1;i<=10;i++){//模擬頁面上按鈕點擊
enque(String.valueOf(i));
try{Thread.sleep(100);}catch(Exception e){}
}
}
}.start();
//2.從佇列取內容(模擬后臺從佇列取資料)
new Thread(){
@Override
public void run() {
for(;;){
String msg=deque();
if(msg==null)continue;
System.out.print(msg);
}
}
}.start();
}
}
五 購物車簡易實作


關鍵代碼實作:
方案一(使用Jedis)來實作
package com.jt.demos;
import redis.clients.jedis.Jedis;
import java.util.Map;
/**
* :基于redis存盤商品購物車資訊
*/
public class CartDemo01 {
public static void addCart(Long userId,Long productId,int num){
//1.建立redis鏈接
Jedis jedis=new Jedis("192.168.126.130",6379);
jedis.auth("123456");
//2.向購物車添加商品
String product = jedis.hget("cart:" + userId, String.valueOf(productId));
//hincrBy這個函式在key不存在時會自動創建key
jedis.hincrBy("cart:" + userId, String.valueOf(productId),num);
//3.釋放redis鏈接
jedis.close();
}
//查看我的購物車
public static Map<String, String> listCart(Long userId){
//1.建立redis鏈接
Jedis jedis=new Jedis("192.168.126.130",6379);
jedis.auth("123456");
//2.查看購物車商品
Map<String, String> map = jedis.hgetAll("cart:" + userId);
//3.釋放redis鏈接
jedis.close();
return map;
}
public static void main(String[] args) {
//1.向購物車添加商品
addCart(101L,201L,1);
addCart(101L,202L,1);
addCart(101L,203L,2);
//2.查看購物車商品
Map<String, String> map = listCart(101L);
System.out.println(map);
}
}
方案二 使用RedisTemplate來實作
package com.jt.redis.demos;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Map;
@Component
public class CartDemo01 {
// @Autowired
@Resource(name="stringRedisTemplate")
private RedisTemplate redisTemplate;
public void addCard(Integer userId,String productId,Integer num){
HashOperations hashOperations = redisTemplate.opsForHash();
hashOperations.increment("cart:"+userId,productId,num);
}
public Map<String,Object> ListCart(Integer userId){
HashOperations hashOperations = redisTemplate.opsForHash();
return hashOperations.entries("cart:"+userId);
}
}
此方案需要重新定義RestTemplat,或者使用 @Resource(name="stringRedisTemplate")
六定制RedisTemplate物件
系統默認的RedisTemplate默認采用的是JDK的序列化機制,假如我們不希望實用JDK的序列化,可以采用的定制RedisTemplate,并采用自己指定的的序列化方式
如果序列化或者反序列化失敗,可能需要重新定義RedisTemplate
package com.jt.redis.config;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
//1.構建RedisTemplate物件
RedisTemplate<Object,Object> redisTemplate=new RedisTemplate<>();
//2.設定連接工廠
redisTemplate.setConnectionFactory(redisConnectionFactory);
//3.定義序列化方式(在這里選擇jackson)
Jackson2JsonRedisSerializer redisSerializer= new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper=new ObjectMapper();
//設定要序列化的域(屬性)
//any表示任意級別訪問修飾符修飾的屬性 private,public,protected
objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
//啟動輸入域檢查(類不能是final修飾的)
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY);
redisSerializer.setObjectMapper(objectMapper);
//4.設定RedisTemplate的序列化
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(redisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(redisSerializer);
//spring規范中假如修改bean物件的默認特性,建議呼叫一下afterPropertiesSet()
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/298356.html
標籤:java
