Java 实现数据隔离 用户只能查看自己所添加的数据 AOP切片注解

1、项目越来越大,数据量越来越多或造成数据查询数据隔离的问题。当角色的判断在代码里面去添加造成数据查询难以维护,维护数量庞大等问题。所以写了一个注解公共方法,实现注解切片自己去判断

package com.mci.aspect;
# 主要方法

#  @Before() 主要是扫描。我所有的模块接口都存放在 com.mci.kjcx 下面。kjcx下面有存放多个模块,我只需要在他们的service里面去添加查询的参数就可以了

#  @annotation() 这个后面给的是我抽象类的地址

@Before("execution(* com.mci.kjcx..service.*.*(..))|| execution(* com.mci.park.service.*.*(..)) && @annotation(com.mci.annotation.DataIsolation)")
    public void checkDataIsolation(JoinPoint joinPoint) {


        // 获取当前用户信息
        SysUser currentUser = null;
        try {
            currentUser = SecurityUtils.getLoginUser().getUser();
        } catch (Exception e) {
            // 处理用户未登录或匿名访问的情况
            // 可以选择记录日志或根据业务需求进行处理
//            System.out.println("匿名访问,无用户信息");
        }

        if (currentUser != null) {
            // 判断当前用户是否为管理员
            if (!isAdmin(currentUser)) {
                // 获取方法的参数
                Object[] args = joinPoint.getArgs();
                for (Object arg : args) {
                    // 使用反射机制,动态为不同的对象设置 created_by 字段
                    setCreatedByField(arg, currentUser.getUserId());
                }
            }
        } else {
            // 处理匿名用户的场景,可能跳过数据隔离,或应用默认过滤条件
//            System.out.println("匿名用户,无需数据隔离");
        }
    }

private boolean isAdmin(SysUser user) {
    // 判断用户是否为管理员,根据角色判断
        return user.getRoles().stream()
                .anyMatch(role -> "超级管理员".equals(role.getRoleName()));
    }


// 使用反射为对象动态设置 created_by 字段
    private void setCreatedByField(Object targetObject, Long userId) {
        try {
            // 获取所有字段
            Field[] fields = targetObject.getClass().getDeclaredFields();
            for (Field field : fields) {
                if ("createdBy".equalsIgnoreCase(field.getName())) {
                    // 允许修改私有字段
                    field.setAccessible(true);
                    // 为字段设置用户ID
                    field.set(targetObject, userId.toString());
                    break;
                }
            }
        } catch (Exception e) {
            // 可以根据需要处理异常,例如日志记录
            e.printStackTrace();
        }
    }


package com.mci.annotation;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)  // 作用于方法
@Retention(RetentionPolicy.RUNTIME)  // 在运行时保留注解
public @interface DataIsolation {
}

这个方法是 @DataIsolation  只要所有的list接口添加了该注解,会执行获取当前登录人的信息,然后去获取当前登录人的ID。

# 使用方法

    /**
     * 查询提诉求列表
     */
    @PreAuthorize("@ss.hasPermi('appeal:appealMessage:list')")
    @GetMapping("/list")
    @DataIsolation
    public TableDataInfo list(CxMakeService cxMakeService)
    {
        startPage();
        List<CxMakeService> list = cxMakeServiceService.selectCxMakeServiceList(cxMakeService);
        return getDataTable(list);
    }

添加了@DataIsolation 就可以自行进行数据隔离的查询了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值