1. 程式人生 > >微信小程式使用redis作為中控伺服器儲存accessToken實現多處共享accessToken

微信小程式使用redis作為中控伺服器儲存accessToken實現多處共享accessToken

使用springboot框架整合, 因為涉及到業務方面的程式碼, 本篇博文沒有寫怎麼獲取access_token ,獲取access_token的方法網上一大片, 隨便copy一個就可以了, 本文主要講解如何整合redis, 然後寫入,查詢,實現多個地方共享access_token

引進依賴

springboot框架整合任何技術都需要從匯入依賴開始, redis也不會例外, 在 common 模組中的gradle.build 檔案的dependencies下面引入 redis的依賴:

 dependencies {
   // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis
   compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis', version: '2.0.4.RELEASE'
   // https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis
   compile group: 'org.springframework.data', name: 'spring-data-redis', version: '2.0.7.RELEASE'
 }

一共是2個依賴包, 一個是 ‘spring-boot-starter-data-redis’, 另外一個是 ‘spring-data-redis’;

配置 redisConfig.java 檔案

api 模組中建立包名config, 並在其下面建立redis的配置檔案:

_20181204173943png

package com.keppel.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.
springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.*; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.
StringRedisSerializer; @Configuration public class RedisConfig { @Autowired RedisConnectionFactory redisConnectionFactory; @Bean public RedisTemplate, Object> functionDomainRedisTemplate() { RedisTemplate, Object> redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } private void initDomainRedisTemplate(RedisTemplate, Object> redisTemplate, RedisConnectionFactory factory) { redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); redisTemplate.setConnectionFactory(factory); } @Bean public HashOperations, String, Object> hashOperations(RedisTemplate, Object> redisTemplate) { return redisTemplate.opsForHash(); } @Bean public ValueOperations, Object> valueOperations(RedisTemplate, Object> redisTemplate) { return redisTemplate.opsForValue(); } @Bean public ListOperations, Object> listOperations(RedisTemplate, Object> redisTemplate) { return redisTemplate.opsForList(); } @Bean public SetOperations, Object> setOperations(RedisTemplate, Object> redisTemplate) { return redisTemplate.opsForSet(); } @Bean public ZSetOperations, Object> zSetOperations(RedisTemplate, Object> redisTemplate) { return redisTemplate.opsForZSet(); } }

配置application.yml檔案

配置檔案加入以下配置

server:
  port: 8080

spring:
  redis: 
    host: 220.49.145.221
    port: 6379
    password: xxxxxxx
    database: 1
    timeout: 5000

實際程式碼操控

首先, 定義一個AccessToken實體類, 注意,以下程式碼均使用了lombok外掛,自動生成get/set方法:

package com.keppel.user.entity;

import lombok.Data;
import java.io.Serializable;
import java.util.Date;

/**
* @Author: keppel
* @Date: Created in 18:33 2018/11/27
* @Description:
*/
@Data
public class AccessToken implements Serializable {
  private String redisKey;
  private Date createAt;
  private String accessToken;
  private Date expireAt;
}

建立基本的IRedisService,實現增刪改查等亂七八糟的方法

 package com.keppel.user.service.redis;

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.HashOperations;
 import org.springframework.data.redis.core.RedisTemplate;

 import javax.annotation.Resource;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;

 /**
  * @Author: YeFei
  * @Date: Created in 18:35 2018/11/27
  * @Description: 
  */
 public abstract class IRedisService<T> {
     @Autowired
     protected RedisTemplate, Object> redisTemplate;
     @Resource
     protected HashOperations, String, T> hashOperations;

     /**
     * 存入redis中的key
     * @return
     */
     protected abstract String getRedisKey();

    /**
     * 新增
     * @param key key
     * @param doamin 物件
     * @param expire 過期時間(單位:秒),傳入 -1 時表示不設定過期時間
     */
     public void put(String key, T doamin, long expire) {
   	  hashOperations.put(getRedisKey(), key, doamin);
   	  if (expire != -1) {
   			redisTemplate.expire(getRedisKey(), expire, TimeUnit.SECONDS);
   	  }
     }

     public void remove(String key) {
   		hashOperations.delete(getRedisKey(), key);
     }

     public T get(String key) {
   		return hashOperations.get(getRedisKey(), key);
     }

     public List<T> getAll() {
   		return hashOperations.values(getRedisKey());
     }

     public Set getKeys() {
   		return hashOperations.keys(getRedisKey());
     }

     public boolean isKeyExists(String key) {
   		return hashOperations.hasKey(getRedisKey(), key);
     }

     public long count() {
   		return hashOperations.size(getRedisKey());
     }

     public void empty() {
   	  Set set = hashOperations.keys(getRedisKey());
   	  set.stream().forEach(key -> hashOperations.delete(getRedisKey(), key));
     }
 }

接著, 建立redis的介面, 使介面實現IReadService介面

  package com.keppel.user.service.redis;

  import com.keppel.user.entity.AccessToken;
  import org.springframework.stereotype.Service;

  /**
   * Created by Administrator on 2017/3/1 16:00. 
   */
  @Service
  public class RedisServiceImpl extends IRedisService {
	private static final String REDIS_KEY = "TEST_REDIS_KEY";

	@Override
	protected String getRedisKey() {
		  return this.REDIS_KEY;
	}
  }

最後新增api新增入口

package com.keppel.api.user;

import com.keppel.user.entity.AccessToken;
import com.keppel.user.entity.User;
import com.keppel.user.service.UserService;
import com.keppel.user.service.redis.RedisServiceImpl;
import com.keppel.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

/**
* @Author: YeFei
* @Date: Created in 0:43 2018/11/24
* @Description:
*/
@RestController
@RequestMapping(value = "/api/v1")
public class UserCtrl {

  @Autowired
  private UserService userService;
  @Autowired
  private RedisServiceImpl redisService;

  @RequestMapping(value = "/save", method = RequestMethod.POST)
  public String saveUser(
  	@RequestBody User user
  ) {
  	return userService.saveUser(user);
  }

  //查詢所有物件
  @RequestMapping(value = "/redis/saveRedis", method = RequestMethod.GET)
  public Object saveRedis() {
  	AccessToken accessToken = new AccessToken();
  	accessToken.setRedisKey("access_token");
  	accessToken.setAccessToken("this is accessToken content1");
  	accessToken.setCreateAt(new Date());
  	accessToken.setExpireAt(DateUtil.getDateAfterMinutes(1, new Date()));
  	redisService.put(accessToken.getRedisKey(), accessToken, -1);
  	return redisService.getAll();
  }

  //查詢所有物件
  @RequestMapping(value = "/redis/getAll", method = RequestMethod.GET)
  public Object getAll() {
  	return redisService.getAll();
  }

  //查詢所有物件
  @RequestMapping(value = "/redis/getByKey", method = RequestMethod.GET)
  public Object getByKey(@RequestParam(value = "key")String key) {
  	return redisService.get(key);
  }
}

大概就是這樣了! AccessToken存到了中控伺服器, 就在也不用擔心多個伺服器同時更新的時候導致accessToken變更請求失敗!