一 单点登陆 代码如下 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; } }