自定義注釋實現權限管理

@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