SpringBoot整合Shiro和Redis的示例代码

demo源码

此demo用SpringBoot+Shiro简单实现了登陆、注册、认证、授权的功能,并用redis做分布式缓存提高性能。

1.准备工作

导入pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
    </parent>
    <groupId>com.ego</groupId>
    <artifactId>shirodemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.13</version>
        </dependency>

        <!-- 引入jsp依赖 -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-starter</artifactId>
            <version>1.5.3</version>
        </dependency>

        <!-- mybatis plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>

        <!-- Druid数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!-- Mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.5.3</version>
        </dependency>
        <!-- 引入redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

    </dependencies>

</project>

配置yml文件

spring:
  # 设置视图模板为jsp
  mvc:
    view:
      prefix: /
      suffix: .jsp
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=UTC
      username: root
      password: root
      # 监控统计拦截的filters
      filters: stat,wall,log4j,config
      # 配置初始化大小/最小/最大
      initial-size: 5
      min-idle: 5
      max-active: 20
      # 获取连接等待超时时间
      max-wait: 60000
      # 间隔多久进行一次检测,检测需要关闭的空闲连接
      time-between-eviction-runs-millis: 60000
      # 一个连接在池中最小生存的时间
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 'x'
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      # 打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
      pool-prepared-statements: false
      max-pool-prepared-statement-per-connection-size: 20
  redis:
    host: 127.0.0.1
    port: 6379
    password: abc123456
    database: 0

mybatis-plus:
  type-aliases-package: com.ego.pojo
  configuration:
    map-underscore-to-camel-case: true

2.编写index,login,register三个JSP

<%--解决页面乱码--%>
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>index</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/user/login" method="post">
        用户名:<input type="text" name="username" > <br/>
        密码  : <input type="text" name="password"> <br>
        <input type="submit" value="登录">
    </form>
</body>
</html>
<%--解决页面乱码--%>
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>index</title>
</head>
<body>
<h1>系统主页</h1>
<a href="${pageContext.request.contextPath}/user/logout">退出用户</a>
<ul>
  <%-- admin角色的用户能同时拥有用户管理和订单管理的权限,user角色的用户只拥有订单管理的权限 --%>
  <shiro:hasRole name="admin">
    <li>
      <a href="">用户管理</a>
    </li>
  </shiro:hasRole>
  <%-- admin角色的用户对订单有增删改查的权限,user角色的用户只能查看订单 --%>
  <shiro:hasAnyRoles name="admin,user">
    <li>
      <a href="">订单管理</a>
      <ul>
        <shiro:hasPermission name="order:add:*">
          <li><a href="">新增</a></li>
        </shiro:hasPermission>
        <shiro:hasPermission name="order:del:*">
          <li><a href="">删除</a></li>
        </shiro:hasPermission>
        <shiro:hasPermission name="order:upd:*">
          <li><a href="">修改</a></li>
        </shiro:hasPermission>
        <shiro:hasPermission name="order:find:*">
          <li><a href="">查询</a></li>
        </shiro:hasPermission>
      </ul>
    </li>
  </shiro:hasAnyRoles>
</ul>
</body>
</html>
<%--解决页面乱码--%>
<%@page contentType="text/html; UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>register</title>
</head>
<body>
<h1>用户注册</h1>
<form action="${pageContext.request.contextPath}/user/register" method="post">
    用户名:<input type="text" name="username" > <br/>
    密码  : <input type="text" name="password"> <br>
    <input type="submit" value="立即注册">
</form>
</body>
</html>

3.实现User、Role、Permission三个POJO

package com.ego.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
 * @author 袁梦达 2019012364
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("t_user")
@ApiModel("用户实体类")
public class User implements Serializable {
    /** 数据库中设置该字段自增时该注解不能少 **/
    @TableId(type = IdType.AUTO)
    @ApiModelProperty(name = "id", value = "ID 主键")
    private Integer id;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "username", value = "用户名")
    private String username;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "password", value = "密码")
    private String password;
    @TableField(fill = FieldFill.INSERT)
    @ApiModelProperty(name = "salt", value = "盐")
    private String salt;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "age", value = "年龄")
    private Integer age;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "email", value = "邮箱")
    private String email;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "address", value = "地址")
    private String address;
    @TableField(exist = false)
    private List<Role> roles = new ArrayList<>();
}
package com.ego.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
 * @author 袁梦达 2019012364
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("t_role")
@ApiModel("角色实体类")
public class Role implements Serializable {
    /** 数据库中设置该字段自增时该注解不能少 **/
    @TableId(type = IdType.AUTO)
    @ApiModelProperty(name = "id", value = "ID 主键")
    private Integer id;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "name", value = "角色名称")
    private String name;
    @TableField(exist = false)
    private List<Permission> permissions = new ArrayList<>();
}
package com.ego.pojo;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
 * @author 袁梦达 2019012364
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("t_permission")
@ApiModel("权限实体类")
public class Permission implements Serializable {
    /** 数据库中设置该字段自增时该注解不能少 **/
    @TableId(type = IdType.AUTO)
    @ApiModelProperty(name = "id", value = "ID主键")
    private Integer id;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "name", value = "权限名称")
    private String name;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty(name = "url", value = "权限菜单URL")
    private String url;
}

4.实现Controller、Service、Dao

这里dao采用了mybatis-plus

package com.ego.controller;
import com.ego.pojo.User;
import com.ego.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * @author 袁梦达 2019012364
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("/login")
    public String login(String username,String password){
        // 获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        try {
            // 执行登录操作
            subject.login(new UsernamePasswordToken(username,password));
            // 认证通过后直接跳转到index.jsp
            return "redirect:/index.jsp";
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户名错误!");
        } catch (IncorrectCredentialsException e) {
            System.out.println("密码错误!");
        } catch (Exception e) {
        }
        // 如果认证失败仍然回到登录页面
        return "redirect:/login.jsp";
    }
    @RequestMapping("/logout")
    public String logout(){
        subject.logout();
        // 退出后仍然会到登录页面
     * 用户注册
     * @param user
    @RequestMapping("/register")
    public String register(User user){
            userService.register(user);
            return "redirect:/login.jsp";
        return "redirect:/register.jsp";
}
package com.ego.service.impl;
import com.ego.dao.mapper.UserMapper;
import com.ego.shiro.ShiroConstant;
import com.ego.utils.SaltUtil;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserServiceImpl implements UserService {
    private UserMapper userMapper;
    @Override
    public void register(User user) {
        //生成随机盐
        String salt = SaltUtil.getSalt(ShiroConstant.SALT_LENGTH);
        //保存随机盐
        user.setSalt(salt);
        //生成密码
        Md5Hash password = new Md5Hash(user.getPassword(), salt, ShiroConstant.HASH_ITERATORS);
        //保存密码
        user.setPassword(password.toHex());
        userMapper.insert(user);
    public User findUserByUserName(String userName) {
        return userMapper.findUserByUserName(userName);
import com.ego.dao.mapper.RoleMapper;
import com.ego.pojo.Role;
import com.ego.service.RoleService;
import java.util.List;
@Service("roleService")
public class RoleServiceImpl implements RoleService {
    private RoleMapper roleMapper;
    public List<Role> getRolesByUserId(Integer userId) {
        return roleMapper.getRolesByUserId(userId);
import com.ego.dao.mapper.PermissionMapper;
import com.ego.pojo.Permission;
import com.ego.service.PermissionService;
@Service("permissionService")
public class PermissionServiceImpl implements PermissionService {
    private PermissionMapper permissionMapper;
    public List<Permission> getPermissionsByRoleId(Integer roleId) {
        return permissionMapper.getPermissionsByRoleId(roleId);
package com.ego.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper extends BaseMapper<User> {
    @Select("SELECT u.id,u.username,u.password,u.salt,u.age,u.email,u.address FROM t_user u WHERE u.username = #{username}")
    User findUserByUserName(String username);
public interface RoleMapper extends BaseMapper<Role> {
    @Select("select r.id,r.name from t_role r left join t_user_role ur on ur.role_id = r.id where ur.user_id = #{userId}")
    List<Role> getRolesByUserId(Integer userId);
public interface PermissionMapper extends BaseMapper<Permission> {
    @Select("select p.id,p.name,p.url from t_permission p left join t_role_permission rp on rp.permission_id = p.id where rp.role_id = #{roleId}")
    List<Permission> getPermissionsByRoleId(Integer roleId);

5.实现SaltUtil和ApplicationContextUtil两个工具类

package com.ego.utils;
import java.util.Random;
/**
 * @author 袁梦达 2019012364
 */
public class SaltUtil {
    public static String getSalt(int n){
        char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890!@#$%^&*()".toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            char aChar = chars[new Random().nextInt(chars.length)];
            sb.append(aChar);
        }
        return sb.toString();
    }
}
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
    public static ApplicationContext context;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    /**
     * 根据工厂中的类名获取类实例
     */
    public static Object getBean(String beanName){
        return context.getBean(beanName);

6.实现核心Shiro

package com.ego.utils;
import java.util.Random;
/**
 * @author 袁梦达 2019012364
 */
public class SaltUtil {
    public static String getSalt(int n){
        char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890!@#$%^&*()".toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            char aChar = chars[new Random().nextInt(chars.length)];
            sb.append(aChar);
        }
        return sb.toString();
    }
}
package com.ego.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
 * @author 袁梦达 2019012364
 */
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
    public static ApplicationContext context;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
    /**
     * 根据工厂中的类名获取类实例
     */
    public static Object getBean(String beanName){
        return context.getBean(beanName);
    }
}

7.实现Redis分布式缓存

package com.ego.shiro;
import com.ego.shiro.cache.RedisCacheManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
 * @author 袁梦达 2019012364
 */
@Configuration
public class ShiroConfiguration {
    //1.创建shiroFilter  //负责拦截所有请求
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //给filter设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        //配置系统受限资源
        //配置系统公共资源
        Map<String,String> map = new HashMap<String,String>();
        map.put("/user/login", "anon");
        map.put("/user/register","anon");
        map.put("/register.jsp","anon");
        map.put("/index.jsp","authc");//authc 请求这个资源需要认证和授权
        //默认认证界面路径
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
    //2.创建安全管理器
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //给安全管理器设置
        defaultWebSecurityManager.setRealm(realm);
        return defaultWebSecurityManager;
    //3.创建自定义realm
    public Realm getRealm(){
        CustomerRealm customerRealm = new CustomerRealm();
        // 设置密码匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        // 设置加密方式
        credentialsMatcher.setHashAlgorithmName(ShiroConstant.HASH_ALGORITHM_NAME.MD5);
        // 设置散列次数
        credentialsMatcher.setHashIterations(ShiroConstant.HASH_ITERATORS);
        customerRealm.setCredentialsMatcher(credentialsMatcher);
        // 设置缓存管理器
        customerRealm.setCacheManager(new RedisCacheManager());
        // 开启全局缓存
        customerRealm.setCachingEnabled(true);
        // 开启认证缓存并指定缓存名称
        customerRealm.setAuthenticationCachingEnabled(true);
        customerRealm.setAuthenticationCacheName("authenticationCache");
        // 开启授权缓存并指定缓存名称
        customerRealm.setAuthorizationCachingEnabled(true);
        customerRealm.setAuthorizationCacheName("authorizationCache");
        return customerRealm;
}
public class ShiroConstant {
    /** 随机盐的位数 **/
    public static final int SALT_LENGTH = 8;
    /** hash的散列次数 **/
    public static final int HASH_ITERATORS = 1024;
    public interface HASH_ALGORITHM_NAME {
        String MD5 = "MD5";
import com.ego.pojo.Permission;
import com.ego.pojo.Role;
import com.ego.pojo.User;
import com.ego.service.PermissionService;
import com.ego.service.RoleService;
import com.ego.service.UserService;
import com.ego.utils.ApplicationContextUtil;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.List;
public class CustomerRealm extends AuthorizingRealm {
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取主身份信息
        String principal = (String) principals.getPrimaryPrincipal();
        // 根据主身份信息获取角色信息
        UserService userService = (UserService) ApplicationContextUtil.getBean("userService");
        User user = userService.findUserByUserName(principal);
        RoleService roleService = (RoleService) ApplicationContextUtil.getBean("roleService");
        List<Role> roles = roleService.getRolesByUserId(user.getId());
        if(!CollectionUtils.isEmpty(roles)){
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            roles.forEach(role -> {
                simpleAuthorizationInfo.addRole(role.getName());
                PermissionService permissionService = (PermissionService) ApplicationContextUtil.getBean("permissionService");
                List<Permission> permissions = permissionService.getPermissionsByRoleId(role.getId());
                if(!CollectionUtils.isEmpty(permissions)){
                    permissions.forEach(permission -> {
                        simpleAuthorizationInfo.addStringPermission(permission.getName());
                    });
                }
            });
            return simpleAuthorizationInfo;
        }
        return null;
    //认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        if(!ObjectUtils.isEmpty(user)){
            return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(), new CustomerByteSource(user.getSalt()),this.getName());
import org.apache.shiro.codec.Base64;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.util.ByteSource;
import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Arrays;
//自定义salt实现  实现序列化接口
public class CustomerByteSource implements ByteSource, Serializable {
    private byte[] bytes;
    private String cachedHex;
    private String cachedBase64;
    public CustomerByteSource() {
    public CustomerByteSource(byte[] bytes) {
        this.bytes = bytes;
    public CustomerByteSource(char[] chars) {
        this.bytes = CodecSupport.toBytes(chars);
    public CustomerByteSource(String string) {
        this.bytes = CodecSupport.toBytes(string);
    public CustomerByteSource(ByteSource source) {
        this.bytes = source.getBytes();
    public CustomerByteSource(File file) {
        this.bytes = (new CustomerByteSource.BytesHelper()).getBytes(file);
    public CustomerByteSource(InputStream stream) {
        this.bytes = (new CustomerByteSource.BytesHelper()).getBytes(stream);
    public static boolean isCompatible(Object o) {
        return o instanceof byte[] || o instanceof char[] || o instanceof String || o instanceof ByteSource || o instanceof File || o instanceof InputStream;
    public byte[] getBytes() {
        return this.bytes;
    public boolean isEmpty() {
        return this.bytes == null || this.bytes.length == 0;
    public String toHex() {
        if (this.cachedHex == null) {
            this.cachedHex = Hex.encodeToString(this.getBytes());
        return this.cachedHex;
    public String toBase64() {
        if (this.cachedBase64 == null) {
            this.cachedBase64 = Base64.encodeToString(this.getBytes());
        return this.cachedBase64;
    public String toString() {
        return this.toBase64();
    public int hashCode() {
        return this.bytes != null && this.bytes.length != 0 ? Arrays.hashCode(this.bytes) : 0;
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (o instanceof ByteSource) {
            ByteSource bs = (ByteSource) o;
            return Arrays.equals(this.getBytes(), bs.getBytes());
        } else {
            return false;
    private static final class BytesHelper extends CodecSupport {
        private BytesHelper() {
        public byte[] getBytes(File file) {
            return this.toBytes(file);
        public byte[] getBytes(InputStream stream) {
            return this.toBytes(stream);

到此这篇关于SpringBoot整合Shiro和Redis的文章就介绍到这了,更多相关SpringBoot整合Shiro和Redis内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot整合Mysql和Redis的详细过程

    目录 一.项目创建 1.1创建项目 1.2目录结构 1.3pom.xml配置文件 二.初始化数据库 三.初始化代码 3.1实体类entity 3.2Mapper接口类 3.3Redis工具类 3.4Service层 3.5Controller层 四.单元测试 4.1Respository和Service层单元测试 4.2Controller层接口测试 一.项目创建 1.1 创建项目 在IDEA中,File--New--Project--Spring Initializer 名称为springbo

  • springboot使用shiro-整合redis作为缓存的操作

    说在前面 本来的整合过程是顺着博客的顺序来的,越往下,集成的越多,由于之前是使用ehcache缓存,现在改为redis,限制登录人数 以及 限制登录次数等 都需要改动,本篇为了简单,目前先将这两个功能下线,配置暂时是注销的,原类保存,在下篇博客中改. 还有之前是使用SessionListener监听session创建来统计在线人数,在本篇中也将改为统计redis中的key数目. 如果是单机,使用ehcache是最快的,项目一般都不是单节点,为了方便之后使用sso单点登录,以及多节点部署,所以使用

  • SpringBoot整合Shiro和Redis的示例代码

    demo源码 此demo用SpringBoot+Shiro简单实现了登陆.注册.认证.授权的功能,并用redis做分布式缓存提高性能. 1.准备工作 导入pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XM

  • SpringBoot 整合 Shiro 密码登录的实现代码

    导入依赖(pom.xml) <!--整合Shiro安全框架--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!--集成jwt实现token认证--> <dependency

  • SpringBoot整合Netty实现WebSocket的示例代码

    目录 一.pom.xml依赖配置 二.代码 2.1.NettyServer 类 2.2.SocketHandler 类 2.3.ChannelHandlerPool 类 2.4.Application启动类 三.测试 一.pom.xml依赖配置 <!-- netty --> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <v

  • SpringBoot整合Shiro实现权限控制的代码实现

    1.SpringBoot整合Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 1.1.shiro简介 shiro有个核心组件,分别为Subject.SecurityManager和Realms Subject:相当于当前操作的"用户",这个用户不一定是一个具体的人,是一个抽象的概念,表明的是和当前程序进行交互的任何东西,例如爬虫.脚本.等等.所有的Subject都绑定到SecurityManager上,与 Subject 的所

  • SpringBoot整合Druid、Redis的示例详解

    目录 1.整合Druid 1.1Druid简介 1.2添加上 Druid 数据源依赖 1.3使用Druid 数据源 2.整合redis 2.1添加上 redis依赖 2.2yml添加redis配置信息 2.3 redis 配置类 1.整合Druid 1.1Druid简介 Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池. Druid 是阿里巴巴开源平台上一个数据库连接池实现,结合了 C3P0.DBCP 等 DB 池的优点,同时加入了日志监控. Druid

  • SpringBoot整合Elasticsearch游标查询的示例代码(scroll)

    游标查询(scroll)简介 scroll 查询 可以用来对 Elasticsearch 有效地执行大批量的文档查询,而又不用付出深度分页那种代价. 游标查询会取某个时间点的快照数据. 查询初始化之后索引上的任何变化会被它忽略. 它通过保存旧的数据文件来实现这个特性,结果就像保留初始化时的索引 视图 一样. 启用游标查询可以通过在查询的时候设置参数 scroll 的值为我们期望的游标查询的过期时间. 游标查询的过期时间会在每次做查询的时候刷新,所以这个时间只需要足够处理当前批的结果就可以了,而不

  • SpringBoot整合分布式锁redisson的示例代码

    目录 1.导入maven坐标 2.redisson配置类(如果redis没有密码就不需要private String password) 3.创建redisson的bean 4.测试,入队 5.测试,出队 6.分布式锁 1.导入maven坐标 <!-- 用redisson作为所有分布式锁,分布式对象等功能框架--> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson&

  • springBoot整合RocketMQ及坑的示例代码

    版本: JDK:1.8 springBoot:1.5.10 rocketMQ:4.2.0 pom 配置: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <d

  • springboot整合Mybatis、JPA、Redis的示例代码

    引言 在springboot 项目中,我们是用ORM 框架来操作数据库变的非常方便.下面我们分别整合mysql ,spring data jpa 以及redis .让我们感受下快车道. 我们首先创建一个springboot 项目,创建好之后,我们来一步步的实践. 使用mybatis 引入依赖: <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-

  • Springboot整合Shiro的代码实例

    这篇文章主要介绍了Springboot整合Shiro的代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.导入依赖 <!--shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</versio

随机推荐