存取用户权限信息 Gradle + Springboot + Java Interceptor + Redis<redisTemplate>

326 阅读2分钟
// redis 支持,
implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.1.4.RELEASE'
implementation 'org.springframework.data:spring-data-redis:2.1.4.RELEASE'

注意事项
springboot版本高于1.4.0,使用spring-boot-starter-data-redis,反之使用spring-boot-starter-redis
引用解答

  • 自定义Interceptor
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * OEM权限 拦截器
 */
public class OemRightInterceptor implements HandlerInterceptor {
    /**
     * 用户 Mapper
     */
    @Resource
    private UserMapper userMapper;

    /**
     * redis 工具类
     */
    @Resource
    private RedisUtil redisUtil;

    /**
     * 拦截OEM,定时更新用户权限
     *
     * @param request request
     * @param response request
     * @param handler request
     * @return OEM判断结果
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 查询redis中uid,不存在则set
        String uid = request.getHeader("uid");
        String rValue = redisUtil.getString("oem_uid_" + uid);
        if (null == rValue) {
            // 查询用户oem权限, 0-非oem 1-oem
            String oem = "0";
            List<UserRightDTO> list = userMapper.getUserRights(Integer.valueOf(uid));
            List<UserRightDTO> oemList = list.stream().filter(z -> z.getModuleCode().equals("W0001")
                    && z.getAccessType().equals(1)).collect(Collectors.toList());
            if (oemList.size() > 0) {
                oem = "1";
            }
            redisUtil.setString("oem_uid_" + uid, oem, Constants.NUMBER_TYPE_SIXTY, TimeUnit.SECONDS);
        }
        // 指定为true,继续执行
        return true;
    }
}
  • Interceptor配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * spring boot 中 拦截器的注册方式
 *
 * WebMvcConfigurer spring配置方式 采用javabean代替XML
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    /**
     * 因为 拦截器加载是在 spring context 加载之前完成的, 需要把拦截器注入到spring中
     * **如果需要在拦截器中,注入service,需要该方法,如果无须注入service,则不需要**
     *
     * @return 拦截器
     */
    @Bean
    public OemRightInterceptor getOemRightInterceptor() {
        return new OemRightInterceptor();
    }

    /**
     * 如果需要在拦截器中,注入service,正确写法
     *
     * @param registry registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getOemRightInterceptor());
    }

    /**
     * 如果需要在拦截器中,注入service,错误写法。 如果无须注入service,则是正确写法
     *
     * 原因:service注入为null的时候,是通过new的方式创建的拦截器,通过new出来的实例是没有交给spring进行管理的,
     *      没有被spring管理的实例,spring是无法自动注入bean的,所以为null
     *
     * @param registry
     */
//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        registry.addInterceptor(new OemRightInterceptor());
//    }
}
  • Redis配置类
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

/**
 * Redis 配置类
 */
@Configuration
public class RedisConfig {
    /**
     * Json序列化,redisTemplate默认使用的是 JdkSerializationRedisSerializer
     *
     * @param redisConnectionFactory redisConnectionFactory
     * @return value
     */
    @Bean
    @ConditionalOnMissingBean(RedisTemplate.class)
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer
                = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 字符序列化,字符串读写
     *
     * @param redisConnectionFactory redisConnectionFactory
     * @return value
     */
    @Bean
    @ConditionalOnMissingBean(StringRedisTemplate.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}
  • Redis工具类
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

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

/**
 * Redis 工具类
 */
@Component
public class RedisUtil {
    /**
     * Json序列化
     */
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * String序列化
     */
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * getJson
     *
     * @param key key
     * @return value
     */
    public Object getJson(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * setJson
     *
     * @param key key
     * @param value value
     * @param timeout timeout
     * @param timeUnit timeUnit
     */
    public void setJson(String key, Object value, long timeout, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * delJson
     *
     * @param key key
     */
    public void delJson(String key) {
        redisTemplate.delete(key);
    }

    /**
     * getString
     *
     * @param key key
     * @return value
     */
    public String getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * setString
     *
     * @param key key
     * @param value value
     * @param timeout timeout
     * @param timeUnit timeUnit
     */
    public void setString(String key, String value, long timeout, TimeUnit timeUnit) {
        stringRedisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * delString
     *
     * @param key key
     */
    public void delString(String key) {
        stringRedisTemplate.delete(key);
    }

}
  • 封装方法
/**
 * 权限Mapper
 */
@Resource
private UserMapper userMapper;

/**
 * redis 工具类
 */
@Resource
private RedisUtil redisUtil;

/**
 * 判断当前账户OEM权限
 *
 * @param uid uid
 * @return 当前账户OEM权限
 */
public boolean judgeUserOemRight(Integer uid) {
    String rValue = redisUtil.getString("oem_uid_" + uid);
    if (null == rValue) {
        List<UserRightDTO> list = userMapper.getUserRights(uid);
        List<UserRightDTO> oemList
                = list.stream().filter(z -> z.getModuleCode().equals("W0001")
                && z.getAccessType().equals(1)).collect(Collectors.toList());
        return oemList.size() > 0;
    } else {
        return rValue.equals("1");
    }
}
  • Redis连接配置
spring.redis.host=10.0.0.8
spring.redis.port=6379
spring.redis.database=7
spring.redis.password=
spring.redis.timeout=5000ms
spring.redis.jedis.pool.max-active=-1
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0