自定义注释实现权限管理

@zgcwkj  2019年01月08日

Java自定义注释实现权限管理 Web项目

首先声明一个注解的 Java 文件

@Retention(RetentionPolicy.RUNTIME)// Retention注解决定注解的生命周期
@Target({ ElementType.TYPE, ElementType.METHOD })// Target注解决定注解可以加在哪些成分上
// 注解上的变量只支持 数据类型中的基本类型,如果不需要注解上的变量,直接留空即刻
// ElementType.TYPE//类上可以加注解
// ElementType.METHOD//函数(方法体)上可以加注解
public @interface 注解名 {
    @AliasFor("str")// 作用说明
    String str() default "";// 注解上的变量
}

使用:

@注解名("")// 默认赋值给第一个注解变量
@注解名(str = "")// 通过 AliasFor 可以直接指定并赋值给某个注解变量

那么问题来了,自定义注解有了,那么我们应该怎么读取呢?

通过 Java 反射可以读取到注解上面的变量,然后拿出来判断,写自己代码

// 如果类名上有注解修饰,则为true
if (类名.class.isAnnotationPresent(注解名.class)) {
    System.out.println("类");

    // 获取方法类上的信息
    注解名 _注解名 = 类名.class.getAnnotation(注解名.class);
    String str = _注解名.str();
    System.out.println(str);
}
Method method = 类名.class.getMethod("函数名");
// 如果函数(方法)上有注解修饰,则为true
if (method.isAnnotationPresent(类名.class)) {
    System.out.println("方法");

    // 获取函数(方法)注解上的信息
    注解名 _注解名 = 类名.class.getAnnotation(注解名.class);
    String str = _注解名.str();
    System.out.println(str);
}

现在很多都用 Spring,可以在 AOP 中直接拿出注解上的信息,并且没有加注解的函数(方法)是不会进入执行的

声明一个 类 ,在类上添加注解

@Aspect
@Component
public class AOP类名

在这个 AOP 类中添加一个环绕通知,在这个方法下可以写自己的代码

@Around(value = "@annotation(注解变量)")
public Object around(ProceedingJoinPoint pjp, 注解类名 注解变量)

获取注解上的数据:

注解变量.变量();

下面是我的权限管理实现代码:

新建 Authorization 类

package com.zgcwkj.config;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;

/**
 * 授权注解
 * 
 * @author zgcwkj
 * @since 2019-01-07
 */
@Retention(RetentionPolicy.RUNTIME)// Retention注解决定注解的生命周期
@Target({ ElementType.TYPE, ElementType.METHOD })// Target注解决定注解可以加在哪些成分上
public @interface Authorization {

}

新建 AOPAuthorization 类

package com.zgcwkj.config;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.alibaba.druid.support.http.WebStatFilter.StatHttpServletResponseWrapper;
import com.zgcwkj.utils.ReturnLayui;

import org.apache.catalina.connector.RequestFacade;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.ModelAndView;
import java.lang.reflect.Method;

/**
 * 授权切入面
 * 
 * @author zgcwkj
 * @since 2019-01-07
 */
@Aspect
@Component
public class AOPAuthorization {

    /**
     * 环绕通知
     * 
     * @param pjp           继续加入点
     * @param authorization 授权信息
     * @return
     * @throws Throwable
     */
    @Around(value = "@annotation(authorization)")
    public Object around(ProceedingJoinPoint pjp, Authorization authorization) throws Throwable {
        HttpSession session = getSession(pjp);
        // ==>验证并读取Session数据
        String userID = String.valueOf(session.getAttribute("userID"));
        String roleID = String.valueOf(session.getAttribute("roleID"));
        if (userID.equals("null") || roleID.equals("null")) {
            return Jumpout(pjp);
        }
        // ==>验证并读取Session数据

        // ==>通过数据库验证是否存在权限

        // ==>通过数据库验证是否存在权限

        Object result = pjp.proceed();
        return result;
    }

    /**
     * 跳转界面
     * 
     * @param pjp 继续加入点
     * @return
     */
    public Object Jumpout(ProceedingJoinPoint pjp) {
        Object returnTarget = null;
        try {
            // ==>反射获取返回类型
            Object[] argObjects = pjp.getArgs();
            Class<?>[] classeP = new Class<?>[argObjects.length];
            for (int i = 0; i < argObjects.length; i++) {
                if (argObjects[i] instanceof RequestFacade) {
                    classeP[i] = HttpServletRequest.class;
                } else if (argObjects[i] instanceof StatHttpServletResponseWrapper) {
                    classeP[i] = HttpServletResponse.class;
                } else {
                    classeP[i] = argObjects[i].getClass();
                }
            }
            Signature signature = pjp.getSignature();
            Class<?> classC = pjp.getTarget().getClass();
            Method method = classC.getMethod(signature.getName(), classeP);
            // ==>反射获取返回类型

            // ==>返回相关参数参数
            returnTarget = method.getReturnType();
            if (returnTarget == String.class) {
                returnTarget = "redirect:/admin/index";
            } else if (returnTarget == ModelAndView.class) {
                returnTarget = new ModelAndView("redirect:/admin/index");
            } else if (returnTarget == ReturnLayui.class) {
                ReturnLayui<?> _object = new ReturnLayui<>();
                _object.setCode(-1);
                _object.setMsg("权限不足");
                returnTarget = _object;
            } else {
                returnTarget = "权限不足";
            }
            // ==>返回相关参数参数
        } catch (Throwable t) {
            returnTarget = t.getMessage();
        }
        return returnTarget;
    }

    /**
     * 获取 Session
     * 
     * @param pjp 继续加入点
     * @return
     */
    public HttpSession getSession(ProceedingJoinPoint pjp) {
        // 获取RequestAttributes
        RequestAttributes rAttributes = RequestContextHolder.getRequestAttributes();
        // // 获取Session信息
        // HttpSession session = request.getSession();
        // 获取Session信息
        HttpSession session = (HttpSession) rAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
        return session;
    }

    /**
     * 获取 Request
     * 
     * @param pjp 继续加入点
     * @return
     */
    public HttpServletRequest getRequest(ProceedingJoinPoint pjp) {
        // 获取RequestAttributes
        RequestAttributes rAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) rAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        return request;
    }
}


添加新评论

Top