shiro(二):springboot整合shiro

1. 整合思路

在这里插入图片描述

2. 加入jsp相关配置方便测试

2.1 加入依赖:

<!--引入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>

2.2 application.properties 文件

server.servlet.context-path=/shiro
spring.application.name=shiro

spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

2.3 添加启动项配置

在这里插入图片描述

2.4 jsp页面代码:

index.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>Document</title>
</head>
<body>
<%--    受限资源--%>
<h1>系统主页</h1>
<%--由于A标签只能发送get请求,如果需要post请求需要使用函数或者其他方式,此处直接get提交,注意项目中尽量post --%>
<a href="${pageContext.request.contextPath}/user/logout">退出登录</a>
<ul>
    <li><a href="#">用户管理</a></li>
    <li><a href="#">商品管理</a></li>
    <li><a href="#">订单管理</a></li>
    <li><a href="#">物流管理</a></li>
</ul>
</body>
</html>

login.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>Document</title>
</head>
<body>
<h1>登录界面</h1>
<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>

2.5 目录结构:

在这里插入图片描述

2.5 查看效果

在这里插入图片描述

3. 关联springboot配置简单使用

3.1 引入依赖

<!--引入shiro整合Springboot依赖-->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-spring-boot-starter</artifactId>
  <version>1.5.3</version>
</dependency>

3.2 配置类编写:

@Configuration
public class ShiroConfig {
    //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("/index.jsp","authc");//authc 请求这个资源需要认证和授权

        //默认认证界面路径---当认证不通过时跳转
        shiroFilterFactoryBean.setLoginUrl("/login.jsp");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

    //2.创建安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //给安全管理器设置
        defaultWebSecurityManager.setRealm(realm);

        return defaultWebSecurityManager;
    }

    //3.创建自定义realm
    // 此处realm中先不加内容直接返回null
    @Bean
    public Realm getRealm(){
        CustomRealm1 customerRealm = new CustomRealm1();

        return customerRealm;
    }
}

3.3 启动错误解决:

3.3.1 报错1:
Parameter 0 of method getDefaultWebSecurityManager in com.yhx.toali.shiroStudy.withSpringboot.ShiroConfig required a single bean, but 2 were found:
- getRealm: defined by method 'getRealm' in class path resource [com/yhx/toali/shiroStudy/withSpringboot/ShiroConfig.class]
- iniClasspathRealm: defined by method 'iniClasspathRealm' in class path resource [org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfiguration.class]

这是因为之前在测试的时候编写了shiro.ini,进入到ShiroAutoConfiguration这个类查看,可以看到根据shiro.ini生成了一个realm:

 @Bean
 @ConditionalOnResource(
     resources = {"classpath:shiro.ini"}
 )
 protected Realm iniClasspathRealm() {
     return this.iniRealmFromLocation("classpath:shiro.ini");
 }
3.3.2 报错2:
Description:

Method filterShiroFilterRegistrationBean in org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration required a bean named 'shiroFilterFactoryBean' that could not be found.


Action:

Consider defining a bean named 'shiroFilterFactoryBean' in your configuration.

设置bean的名称:@Bean("shiroFilterFactoryBean")

3.4 启动项目查看index.jsp

可以看到访问index.jsp自动跳到了login.jsp
在这里插入图片描述

4. 常见过滤器

shiro提供和多个默认的过滤器,我们可以用这些过滤器来配置控制指定url的权限:

其中主要使用的是anon和authc
在这里插入图片描述

5. 认证的登陆和退出实现

5.1 controller方法编写:

@Controller
@RequestMapping("user")
public class UserController {
    /**
     * 退出登录
     */
    @PostMapping("logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();//退出用户
        return "redirect:/login.jsp";
    }

    /**
     * 用来处理身份认证
     * @param username
     * @param password
     * @return
     */
    @PostMapping("login")
    public String login(String username, String password) {
        try {
            //获取主体对象
            Subject subject = SecurityUtils.getSubject();
            // 在认证过程中使用subject.login进行认证
            subject.login(new UsernamePasswordToken(username, password));
            return "redirect:/index.jsp";
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户名错误!");
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            System.out.println("密码错误!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }

        return "redirect:/login.jsp";
    }
}

5.2 jsp页面事件触发

上面jsp页面代码已有,此处略

5.3 修改自定义realm实现登陆验证

//自定义realm
public class CustomRealm1 extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("=============");
        //从传过来的token获取到的用户名
        String principal = (String) token.getPrincipal();
        System.out.println("用户名"+principal);

        //假设是从数据库获得的 用户名,密码
        String password_db="123";
        String username_db="zhangsan";

        if (username_db.equals(principal)){
//            SimpleAuthenticationInfo simpleAuthenticationInfo =
            return new SimpleAuthenticationInfo(principal,password_db, this.getName());
        }

        return null;
    }
}

5.4 修改shiroConfig类中的getShiroFilterFactoryBean()方法进行资源限制:

@Bean("shiroFilterFactoryBean")
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");//anon 设置为公共资源 
    map.put("/user/register","anon");//anon 设置为公共资源
    map.put("/register.jsp","anon");//anon 设置为公共资源
    map.put("/user/getImage","anon");

    map.put("/**","authc");//authc 请求这个资源需要认证和授权

    //默认认证界面路径---当认证不通过时跳转
    shiroFilterFactoryBean.setLoginUrl("/login.jsp");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

    return shiroFilterFactoryBean;
}

5.5 测试

登录正常,登出正常,未登录和登出后不能访问index.jsp

6. MD5、Salt的认证实现

6.1 springboot整合数据库及mybatis

6.2 数据库表结构及相关对象类添加:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `username` varchar(40) DEFAULT NULL,
  `password` varchar(40) DEFAULT NULL,
  `salt` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;

在这里插入图片描述
user的entity:

@Data
@TableName("t_user")
public class User {
    @TableId(value = "id", type= IdType.AUTO)
    private String  id;
    @TableField("username")
    private String username;
    @TableField("password")
    private String password;
    @TableField("salt")
    private String salt;
}

service、mapper、xml略

6.3 创建salt工具类

public class SaltUtils {
    /**
     * 生成salt的静态方法
     * @param n
     * @return
     */
    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();
    }
}

6.4 注册相关代码:

6.4.1 添加注册页面:
<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>
6.4.2 在shiroconfig中添加权限通过
map.put("/user/register","anon");//anon 设置为公共资源 
map.put("/register.jsp","anon");//anon 设置为公共资源  
6.4.3 编写java代码:
@RequestMapping("register")
public String register(User user) {
    try {
        //处理业务调用dao
        //1.生成随机盐
        String salt = SaltUtils.getSalt(8);
        //2.将随机盐保存到数据
        user.setSalt(salt);
        //3.明文密码进行md5 + salt + hash散列
        Md5Hash md5Hash = new Md5Hash(user.getPassword(),salt,1024);
        user.setPassword(md5Hash.toHex());
        userService.save(user);
        return "redirect:/login.jsp";
    }catch (Exception e){
        e.printStackTrace();
        return "redirect:/register.jsp";
    }
}
6.4.4 结果测试:

在这里插入图片描述

6.5 登陆相关代码:

6.5.1 添加自定义realm
//自定义realm
public class CustomRealm2 extends AuthorizingRealm {

	@Autowired
    private IUserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
         //根据身份信息//从传过来的token获取到的用户名
        String principal = (String) token.getPrincipal();

        //根据身份信息查询
        User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, principal));
        System.out.println("User:"+user);

        //用户不为空
        if(!ObjectUtils.isEmpty(user)){
            //返回数据库信息
            // 这里进行数据库中密码和登陆输入密码加盐对比
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(),
                    ByteSource.Util.bytes(user.getSalt()), this.getName());
            return simpleAuthenticationInfo;
        }

        return null;
    }
}
6.5.2 修改ShiroConfig中realm

使用凭证匹配器以及hash散列

以及在 getShiroFilterFactoryBean 中添加公共资源

@Bean
public Realm getRealm(){
    CustomRealm2 customerRealm = new CustomRealm2();
    //设置hashed凭证匹配器
    HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
    //设置md5加密
    credentialsMatcher.setHashAlgorithmName("md5");
    //设置散列次数
    credentialsMatcher.setHashIterations(1024);
    customerRealm.setCredentialsMatcher(credentialsMatcher);
    return customerRealm;
}

7. 授权实现

7.1 非数据库方式实现:

7.1.1 页面资源授权

在页面的标签上添加权限控制,其中:

  • shiro:hasAnyRoles :是当用户有以下权限时,才能访问此资源
  • shiro:hasPermission :是当用户有此资源访问权限时,才能访问此资源
<%@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>Document</title>
</head>
<body>
<%--    受限资源--%>
<h1>系统主页</h1>
<a href="${pageContext.request.contextPath}/user/logout">退出登录</a>
<ul>
    <shiro:hasAnyRoles name="user_manager,admin,addinfo_manager">
        <li><a href="">用户管理</a>
            <ul>
                <shiro:hasPermission name="user:add:*">
                    <li><a href="">添加</a></li>
                </shiro:hasPermission>
                <shiro:hasPermission name="user:delete:*">
                    <li><a href="">删除</a></li>
                </shiro:hasPermission>
                <shiro:hasPermission name="user:update:*">
                    <li><a href="">修改</a></li>
                </shiro:hasPermission>
                <shiro:hasPermission name="user:find:*">
                    <li><a href="">查询</a></li>
                </shiro:hasPermission>
            </ul>
        </li>
    </shiro:hasAnyRoles>
    <shiro:hasAnyRoles name="order_manager,admin,addinfo_manager">
        <li><a href="">订单管理</a></li>
        <ul>
            <shiro:hasPermission name="order:add:*">
                <li><a href="">添加</a></li>
            </shiro:hasPermission>
            <shiro:hasPermission name="order:delete:*">
                <li><a href="">删除</a></li>
            </shiro:hasPermission>
            <shiro:hasPermission name="order:update:*">
                <li><a href="">修改</a></li>
            </shiro:hasPermission>
            <shiro:hasPermission name="order:find:*">
                <li><a href="">查询</a></li>
            </shiro:hasPermission>
        </ul>
    </shiro:hasAnyRoles>
    <shiro:hasRole name="admin">
        <li><a href="">商品管理</a></li>
        <li><a href="">物流管理</a></li>
    </shiro:hasRole>

    <shiro:hasRole name="user">
        <li><a href="">仅普通用户可见</a></li>
        <li><a href="">公共资源</a></li>
    </shiro:hasRole>
</ul>
</body>
</html>

7.1.2 代码方式授权

修改保存接口,只有admin的角色才能进行访问:

@RequestMapping("save")
public String save(){
  System.out.println("进入方法");
  
  //基于角色
  //获取主体对象
  Subject subject = SecurityUtils.getSubject();
  //代码方式
  if (subject.hasRole("admin")) {
    System.out.println("保存订单!");
  }else{
    System.out.println("无权访问!");
  }
  //基于权限字符串
  //....
  return "redirect:/index.jsp";
}
7.1.3 方法调用授权
  • @RequiresRoles 用来基于角色进行授权
  • @RequiresPermissions 用来基于权限进行授权
@Controller
@RequestMapping("order")
public class OrderController {

    @RequiresRoles(value={"admin","user"})//用来判断角色  同时具有 admin user
    @RequiresPermissions("user:update:01") //用来判断权限字符串
    @RequestMapping("save")
    public String save(){
        System.out.println("进入方法");
        return "redirect:/index.jsp";
    }
}
7.1.4 修改CustomRealm2的权限认证方法:
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    //获取身份信息
    String primaryPrincipal = (String) principals.getPrimaryPrincipal();
    System.out.println("调用授权验证: "+primaryPrincipal);
    //根据主身份信息获取角色 和 权限信息
    if ("xiaochen".equals(primaryPrincipal)) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole("admin");
        authorizationInfo.addRole("admin");

        authorizationInfo.addStringPermission("user:find:*");
        authorizationInfo.addStringPermission("user:update:*");
        authorizationInfo.addStringPermission("order:update:*");

        return authorizationInfo;
    }

    return null;
}
7.1.5 测试

在这里插入图片描述

7.2 数据库方式实现:

在这里插入图片描述

7.2.1 数据库添加
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_perms
-- ----------------------------
DROP TABLE IF EXISTS `t_perms`;
CREATE TABLE `t_pers` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `name` varchar(80) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_role
-- ----------------------------
DROP TABLE IF EXISTS `t_role`;
CREATE TABLE `t_role` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `name` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_role_perms
-- ----------------------------
DROP TABLE IF EXISTS `t_role_perms`;
CREATE TABLE `t_role_perms` (
  `id` int(6) NOT NULL,
  `roleid` int(6) DEFAULT NULL,
  `permsid` int(6) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `username` varchar(40) DEFAULT NULL,
  `password` varchar(40) DEFAULT NULL,
  `salt` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for t_user_role
-- ----------------------------
DROP TABLE IF EXISTS `t_user_role`;
CREATE TABLE `t_user_role` (
  `id` int(6) NOT NULL,
  `userid` int(6) DEFAULT NULL,
  `roleid` int(6) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 1;

在这里插入图片描述

7.2.2 相关实体类及查询语句添加

7.2.3 复制CustomRealm2为CustomRealm3,修改其中授权方法:
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    //获取身份信息
    String primaryPrincipal = (String) principals.getPrimaryPrincipal();
    System.out.println("调用授权验证: "+primaryPrincipal);
    //根据主身份信息获取角色 和 权限信息
    User user = userService.findRolesByUserName(primaryPrincipal);
    System.out.println("user:"+user);

    //授权角色信息
    if(!CollectionUtils.isEmpty(user.getRoles())){
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        user.getRoles().forEach(role->{
            simpleAuthorizationInfo.addRole(role.getName()); //添加角色信息

            //权限信息
            List<Perm> perms = userService.findPermsByRoleId(role.getId());
            System.out.println("perms:"+perms);

            if(!CollectionUtils.isEmpty(perms) && perms.get(0)!=null ){
                perms.forEach(perm->{
                    simpleAuthorizationInfo.addStringPermission(perm.getName());
                });
            }
        });
        return simpleAuthorizationInfo;
    }
    return null;
}
7.2.4 数据库数据添加

在这里插入图片描述

  • 用户 admin 具有 admin的角色,具有 对于 user,order的所有权限
  • 用户 zhangsan 具有 user的角色,没有权限,只能访问公共资源
  • 用户 usermanager 具有 user_manager的角色,具有 对于 user的所有权限
  • 用户 ordermanager 具有 order_manager的角色,具有 对于 order的所有权限
  • 用户 addinfomanager 具有 addinfo_manager的角色,具有 对于 user,order 的添加权限
7.2.5 测试:

在这里插入图片描述

8. shiro结合缓存

作用:减轻数据库压力

示意图:
在这里插入图片描述

8.1 使用shiro中默认EhCache实现缓存

8.1.1 添加依赖
<!--引入shiro和ehcache-->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-ehcache</artifactId>
  <version>1.5.3</version>
</dependency>

8.1.2 代码修改
@Bean
public Realm getRealm(){
    CustomRealm2 customerRealm = new CustomRealm2();
    //设置hashed凭证匹配器
    HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
    //设置md5加密
    credentialsMatcher.setHashAlgorithmName("md5");
    //设置散列次数
    credentialsMatcher.setHashIterations(1024);
    customerRealm.setCredentialsMatcher(credentialsMatcher);

    //开启缓存管理器
    customerRealm.setCacheManager(new EhCacheManager());
    customerRealm.setCachingEnabled(true); // 开启全局缓存
    customerRealm.setAuthorizationCachingEnabled(true); // 授权缓存
    customerRealm.setAuthenticationCachingEnabled(true);// 认证缓存
    
    return customerRealm;
}
8.1.3 测试

登陆后刷新页面发现没有再走数据库查询代码

8.1.3 优缺点
  • 优点:
    • 无需自己编写代码,shiro和ehcache集成,登录后自动缓存登陆信息
  • 缺点:
    • 应用内缓存,一但服务宕机,缓存也随机消失
    • 不适用于分布式项目

8.2 使用redis作为缓存

8.2.1 redis配置

8.2.2 创建redis的缓存管理器

通过查看ehcache的源码,可以看到其实实现了CacheManager接口,所以这里我们自定义redis的缓存管理器实现CacheManager接口

//自定义shiro缓存管理器
public class RedisCacheManager implements CacheManager {

    //参数1:认证或者是授权缓存的统一名称
    @Override
    public <K, V> Cache<K, V> getCache(String cacheName) throws CacheException {
        System.out.println(cacheName);
        return new RedisCache<K,V>(cacheName);
    }
}

从上述返回值来看,如果要取缓存,还得用到shiro的Cache<K, V>的实现,所以我们还得自定义一个类来实现Cache<K, V>接口

8.2.3 自定义redis缓存实现

此实现类中的方法即shiro自动缓存访问的方法。

//自定义redis缓存的实现
public class RedisCache<k,v> implements Cache<k,v> {

    private String cacheName;

    public RedisCache() {
    }

    public RedisCache(String cacheName) {
        this.cacheName = cacheName;
    }

    @Override
    public v get(k k) throws CacheException {
        System.out.println("get key:"+k);
        return (v) getRedisTemplate().opsForHash().get(this.cacheName,k.toString());
    }

    @Override
    public v put(k k, v v) throws CacheException {
        System.out.println("put key: "+k);
        System.out.println("put value:"+v);
        getRedisTemplate().opsForHash().put(this.cacheName,k.toString(),v.toString());
        return null;
    }

    @Override
    public v remove(k k) throws CacheException {
        System.out.println("=============remove=============");
        return (v) getRedisTemplate().opsForHash().delete(this.cacheName,k.toString());
    }

    @Override
    public void clear() throws CacheException {
        System.out.println("=============clear==============");
        getRedisTemplate().delete(this.cacheName);
    }

    @Override
    public int size() {
        return getRedisTemplate().opsForHash().size(this.cacheName).intValue();
    }

    @Override
    public Set<k> keys() {
        return getRedisTemplate().opsForHash().keys(this.cacheName);
    }

    @Override
    public Collection<v> values() {
        return getRedisTemplate().opsForHash().values(this.cacheName);
    }

    private RedisTemplate getRedisTemplate(){
        RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtils.getBean("redisTemplate");
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}
8.2.4 启动登陆测试:

在这里插入图片描述

9. 加入验证码验证

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值