每次登录load菜单列表,登录加载时间长,将每种角色菜单列表缓存到redis中

每次登录load菜单列表,登录加载时间长,将每种角色菜单列表缓存到redis中

思路:redis菜单列表每次登录查询当前登录的角色是否存入redis
如果存入直接取redis数据,如果redis没有,则登录获取菜单list,并存入redis
,首次登录慢加载list,以后登录直接从redis获取
当菜单删除时候将key删除掉,当重新授权时候将redis的key删掉,这样便控制了redis缓存的菜单信息是最新的

package com.shijie.box.admin.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.subject.Subject;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.shijie.box.admin.util.SerializeUtils;
import com.shijie.box.db.dto.ApiResult;
import com.shijie.box.db.dto.admin.MenuVo;
import com.shijie.box.db.dto.admin.RoleInfo;
import com.shijie.box.db.entity.BaseUser;
import com.shijie.box.db.service.BaseMenuService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/admin/auth")
@Validated
@Api("登录及权限相关api")
public class AdminAuthController {
    private final Log logger = LogFactory.getLog(AdminAuthController.class);
    
    @Autowired
    private BaseMenuService baseMenuService;
    
    @Autowired
	  private StringRedisTemplate redisTemplate;


    @RequiresAuthentication
    @GetMapping("/info")
    @ApiOperation("获取菜单权限 api")
    @ResponseBody
    public ApiResult<RoleInfo> info() {
    	ApiResult<RoleInfo>  rest= new ApiResult<RoleInfo>();
        Subject currentUser = SecurityUtils.getSubject();
        BaseUser admin = (BaseUser) currentUser.getPrincipal();
        RoleInfo info=new RoleInfo();
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("userId", admin.getId());
        String roleIds = admin.getUserrole();
      //  ShoppingUserRole shoppingUserRole=shoppingUserRoleServiceImpl.listBy(paramMap);
     //   Set<String> roles = null;//roleService.queryByIds(roleIds);
        List<MenuVo> listmentVo;
        List<String> roleperms;
        
        //判断当前roleId的key是否存在,存在直接从redis取,不存在查询数据库并存放redis
        Boolean flag = redisTemplate.opsForHash().hasKey(roleIds, "listmentVobyte");
        logger.info("判断redis是否存在当前角色,角色:"+roleIds+",是否存在:"+flag);
        if(flag) {
        	logger.info("进入从redis获取菜单等数据信息");
        	//redis取数据
        	String strlistmentVo = (String)redisTemplate.opsForHash().get(roleIds, "listmentVobyte");
        	String strroleperms = (String)redisTemplate.opsForHash().get(roleIds, "rolepermsbyte");
        	listmentVo=(List<MenuVo>)SerializeUtils.deSerialize(Base64.decodeBase64(strlistmentVo));
            roleperms=(List<String>)SerializeUtils.deSerialize(Base64.decodeBase64(strroleperms));
        }else {
        	logger.info("首次存角色,并查询数据库:"+roleIds);
        	listmentVo=baseMenuService.listMenuByRoleByParentId(roleIds,0L);
            roleperms=baseMenuService.listAllUrlByRole(roleIds);
//            //数据存入redis
            byte[] listmentVobyte = SerializeUtils.serialize(listmentVo);
            byte[] rolepermsbyte = SerializeUtils.serialize(roleperms);
            
            logger.info("存数据到redis");
            redisTemplate.opsForHash().put(roleIds, "listmentVobyte", Base64.encodeBase64String(listmentVobyte));
            redisTemplate.opsForHash().put(roleIds, "rolepermsbyte", Base64.encodeBase64String(rolepermsbyte));
        }
        
       // listmentVo =this.recursion(listmentVo);
        List<String> rolesList=  new ArrayList<String>();
        rolesList.add(roleIds);
        info.setRoles(rolesList);
        info.setAvatar(admin.getWxPhoto());
        info.setName(admin.getUsername());
        info.setPerms(listmentVo);
        info.setRoleperms(roleperms);
        rest.setData(info);
        return rest;
    }

}

序列化utils类

package com.shijie.box.admin.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeUtils {
	public static byte[] serialize(Object obj) {
		byte[] bytes = null;
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			;
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(obj);
			bytes = baos.toByteArray();
			baos.close();
			oos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bytes;
	}

	public static Object deSerialize(byte[] bytes) {
		Object obj = null;
		try {
			ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
			ObjectInputStream ois = new ObjectInputStream(bais);
			obj = ois.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}
}

以上开始思路是将获取菜单列表的list使用json格式化,然后保存格式化后的json文本保存redis,然后再redis读出来,由于MenuVo这个对象里面有个属性,如下:children,是list格式的,在反json成对象时候会出现错误,于是,使用对象序列化解决问题,在上面先得到对象序列化后的byte,然后使用base64转成字符串,保存入redis,开始直接保存byte[]类型到redis,在反学序列化时候出错,可能通过redis存取,byte[]数据有些许变化,所有转成字符串,用redis读出来后在转成byte[],然后在反序列化,解决问题.

public class MenuVo implements Serializable{
	
	private String id;
	private String parentId;
	private String path;
	private String component;
	private String redirect;
	private String alwaysShow;
	private String name;
	private String role;
	private Map<String,Object> meta;
	private List<MenuVo> children ;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getParentId() {
		return parentId;
	}
	public void setParentId(String parentId) {
		this.parentId = parentId;
	}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangyue23com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值