java privilege的用法_java反射--注解的定義與運用以及權限攔截

自定義注解類編寫的一些規則:

1. Annotation型定義為@interface, 所有的Annotation會自動繼承java.lang.Annotation這一接口,并且不能再去繼承別的類或是接口.

2. 參數成員只能用public或默認(default)這兩個訪問權修飾

3. 參數成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數據類型和String、Enum、Class、annotations等數據類型,以及這一些類型的數組.

4. 要獲取類方法和字段的注解信息,必須通過Java的反射技術來獲取 Annotation對象,因為你除此之外沒有別的獲取注解對象的方法

5. 注解也可以沒有定義成員, 不過這樣注解就沒啥用了

自定義注解類時, 可以指定目標 (類、方法、字段, 構造函數等) , 注解的生命周期(運行時,class文件或者源碼中有效), 是否將注解包含在javadoc中及是否允許子類繼承父類中的注解, 具體如下:

1. @Target 表示該注解目標,可能的 ElemenetType 參數包括:

ElemenetType.CONSTRUCTOR 構造器聲明

ElemenetType.FIELD 域聲明(包括 enum 實例)

ElemenetType.LOCAL_VARIABLE 局部變量聲明

ElemenetType.METHOD 方法聲明

ElemenetType.PACKAGE 包聲明

ElemenetType.PARAMETER 參數聲明

ElemenetType.TYPE 類,接口(包括注解類型)或enum聲明

2.?@Retention 表示該注解的生命周期,可選的 RetentionPolicy 參數包括

RetentionPolicy.SOURCE 注解將被編譯器丟棄

RetentionPolicy.CLASS 注解在class文件中可用,但會被VM丟棄

RetentionPolicy.RUNTIME VM將在運行期也保留注釋,因此可以通過反射機制讀取注解的信息

3. @Documented 指示將此注解包含在 javadoc 中

4.??@Inherited 指示允許子類繼承父類中的注解

類注解的定義:

importjava.lang.annotation.ElementType;

importjava.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

importjava.lang.annotation.Target;

/**

*?注解類

*?@author?Owner

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)

public@interfaceMyClassAnnotation?{

String?uri();

String?desc();

}

構造方法注解定義:

importjava.lang.annotation.ElementType;

importjava.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

importjava.lang.annotation.Target;

/**

*?構造方法注解

*?@author?Owner

*

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.CONSTRUCTOR)

public@interfaceMyConstructorAnnotation?{

String?uri();

String?desc();

}

方法注解定義:

importjava.lang.annotation.ElementType;

importjava.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

importjava.lang.annotation.Target;

/**

*?我的方法注解

*?@author?Owner

*

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public@interfaceMyMethodAnnotation?{

String?uri();

String?desc();

}

字段注解定義:

importjava.lang.annotation.ElementType;

importjava.lang.annotation.Retention;

importjava.lang.annotation.RetentionPolicy;

importjava.lang.annotation.Target;

/**

*?字段注解定義

*?@author?Owner

*

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

public@interfaceMyFieldAnnotation?{

String?uri();

String?desc();

}

最后定義一個測試類

importjava.lang.reflect.Constructor;

importjava.lang.reflect.Field;

importjava.lang.reflect.Method;

@MyClassAnnotation(desc="The?class?name",?uri="com.annotation.MySample")

publicclassMyTest?{

@MyFieldAnnotation(desc="The?class?field",?uri="com.annotation.MySample#id")

privateintid;

@MyConstructorAnnotation(desc="The?class?constructor",?uri="com.annotation.MySample#MySample")

publicMyTest(){}

publicintgetId()?{

returnid;

}

@MyMethodAnnotation(desc="The?class?method",?uri="com.annotation.MySample#setId")

publicvoidsetId(intid)?{

this.id?=?id;

}

publicstaticvoidmain(String[]?args)throwsException?{

Class?clazz?=?MyTest.class;

//得到類注解

MyClassAnnotation?myClassAnnotation?=?clazz.getAnnotation(MyClassAnnotation.class);

System.out.println(myClassAnnotation.desc()+"?"+myClassAnnotation.uri());

//得到構造方法注解

Constructor?cons?=?clazz.getConstructor(newClass[]{});

MyConstructorAnnotation?myConstructorAnnotation?=?cons.getAnnotation(MyConstructorAnnotation.class);

System.out.println(myConstructorAnnotation.desc()+"?"+myConstructorAnnotation.uri());

//獲取方法注解

Method?method?=?clazz.getMethod("setId",newClass[]{int.class});

MyMethodAnnotation?myMethodAnnotation?=?method.getAnnotation(MyMethodAnnotation.class);

System.out.println(myMethodAnnotation.desc()+"?"+myMethodAnnotation.uri());

//獲取字段注解

Field?field?=?clazz.getDeclaredField("id");

MyFieldAnnotation?myFieldAnnotation?=?field.getAnnotation(MyFieldAnnotation.class);

System.out.println(myFieldAnnotation.desc()+"?"+myFieldAnnotation.uri()?);

}

}

輸出:

The class name com.annotation.MySample

The class constructor com.annotation.MySample#MySample

The class method com.annotation.MySample#setId

The class field com.annotation.MySample#id

好了,上面是基本學習,我們在實際的項目中用在什么地方呢?我想我們都做過關于細粒度權限攔截的問題,在Struts2中可以根據登錄用戶所具有的的權限進行任

@Retention(RetentionPolicy.RUNTIME)//代表Permission注解保留在的階段

@Target(ElementType.METHOD)//標注在方法上面

public@interfacePermission?{

/**?模塊?*/

String?module();

/**?權限值?*/

String?privilege();

}

比如有一個部門action,Department.action,有一個方法public String departmentlistUI(){}

可以這樣定義方法

@Permission(module="department",privilege="view")

publicString?departmentlistUI(){

}

然后自定定義一個權限攔截器PrivilegeInterceptor.java并在struts.xml中注冊,

在實現interceptor接口后,實現方法public String intercept(ActionInvocation invocation) throws Exception {}

在這里調用任一個action方法都會經過該攔截方法,通過invocation可以獲取當前調用的action的名字,以及調用的action的哪個方法,

通過這段代碼可以獲取action名字和方法名

String??actionName=invocation.getProxy().getActionName();

String??methodName=invocation.getProxy().getMethod();

System.out.println("攔截到:action的名字:"+actionName+"方法名:"+methodName);

然后通過反射技術,獲取該方法上的自定義權限注解,獲取當前登錄的用戶(從session中),遍歷當前用戶的所擁有的權限組,并且遍歷任一個權限組下的所有的權限,看是否包括該方法上注解所需的權限。這樣就可以完成細粒度的action方法權限攔截了。

這只是個大體的思路

下面看一下,攔截器的具體實現該功能的代碼

privatebooleanvalidate(ActionInvocation?invocation)throwsSecurityException,?NoSuchMethodException?{

String??methodName=invocation.getProxy().getMethod();

Method?currentMethod?=?invocation.getAction().getClass().getMethod(methodName);

if(currentMethod?!=null&&?currentMethod.isAnnotationPresent(Permission.class)){

//得到方法上的注解

Permission?permission?=?currentMethod.getAnnotation(Permission.class);

//該方法上的所需要的權限

SystemPrivilege?methodPrivilege?=?newSystemPrivilege(newSystemPrivilegePK(permission.module(),?permission.privilege()));

//得到當前登錄的用戶

Employee?e?=?(Employee)?ActionContext.getContext().getSession().get("loginUser");

//遍歷當前用戶下的所有的權限組

for(PrivilegeGroup?group?:?e.getGroups()){

//如果該權限組下包含,要訪問該方法所需要的權限,就放行

if(group.getPrivileges().contains(methodPrivilege)){

returntrue;

}

}

//說明遍歷的該用戶所有的權限組,沒有發現該權限,說明沒有該權限

returnfalse;

}

//沒有標注注解,表示誰都可以調用該方法

returntrue;

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373407.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373407.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373407.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WinForm------TextEdit只能輸入數字

代碼: this.textEdit1.Properties.Mask.EditMask "\d"; this.textEdit1.Properties.Mask.MaskType MaskType.RegEx; 轉載于:https://www.cnblogs.com/tianhengblogs/p/6093634.html

mysql使用隨筆

mysql 刪除語句 :delete from 表名 where 條件; 例如 delete from tbuserinfo where id 2;mysql 查詢語句 :select * 列名 from 表名 where 條件;mysql 模糊查詢 : SELECT * FROM 表名 WHERE 列名 LIKE "3%&qu…

JavaFX:創建Sprite動畫

到目前為止,盡管我的大多數文章都涉及JavaFX屬性和綁定,但今天我想寫一講我也致力于JavaFX運行時的另一部分:動畫API。 在本文中,我將解釋如何在JavaFX中編寫自定義動畫,以及如何使用這種方法為Sprite動畫創建類。 &am…

java tick_Java中的Clock tick()方法

可以使用tick()Java中Clock類中的方法在所需的時間范圍內舍入基本時鐘的瞬間。此方法需要兩個參數,即基本時鐘和滴答的持續時間。同樣,返回在所需持續時間內四舍五入的基本時鐘時刻。演示此的程序如下所示-示例import java.time.*;public class Main {pu…

JAVA 常用框架和工具

集成開發工具(IDE):Eclipse、MyEclipse、Spring Tool Suite(STS)、Intellij IDEA、NetBeans、JBuilder、JCreator JAVA服務器:tomcat、jboss、websphere、weblogic、resin、jetty、apusic、apache 負載均衡…

MySQL Doublewrite Buffer及業務評估

1. 關于Doublewrite Buffe的總結 Doublewrite Buffer:Doublewrite Buffer出現的初衷是防止buffer pool中的臟頁刷新到磁盤中,出現部分寫的問題,innodb頁大小一般為16k,而Linux操作系統的block size一般為4k。這樣在刷新的過程中&a…

使用UIBinder的GWT自定義按鈕

這是一個有關如何在GWT上使用UIBinder創建自定義按鈕的示例。 public class GwtUIBinderButton implements EntryPoint {public void onModuleLoad() {Button button new Button();button.setText("Button");button.addClickHandler(new ClickHandler(){Overridepub…

delete postman 傳參_PostMan 傳參boolean 類型,接口接受的值一直是false

情形:最近寫前臺頁面的一個按鈕,功能是:點擊后切換狀態,顯示是或否。字段名稱是isTest,類型是boolean 。寫完接口,拿postMan測試,傳參如下:但是后臺接口接受的數據 一直是false,處理&#xff1a…

前端學PHP之文件操作

前端學PHP之文件操作 前面的話 在程序運行時,程序本身和數據一般都存在內存中,當程序運行結束后,存放在內存中的數據被釋放。如果需要長期保存程序運行所需的原始數據,或程序運行產生的結果,就需要把數據存儲在文件或數…

騰訊云CentOS6.5下安裝mysql,并配置好遠程訪問等權限,途中遇到的問題

1.使用yum命令安裝mysql [rootbogon ~]# yum -y install mysql-server 2.設置開機啟動 [rootbogon ~]# chkconfig mysqld on 3.啟動MySQL服務 [rootbogon ~]# service mysqld start 4.設置MySQL的root用戶設置密碼 [rootbogon ~]# mysql -u root mysql> select u…

休眠性能提示:臟收集效果

在使用Hibernate作為ORM開發服務器和嵌入式應用程序8年后,我全力以赴地尋求提高Hibernate性能的解決方案,閱讀博客和參加會議,我決定與您分享這幾年獲得的知識。 這是更多新帖子中的第一篇: 去年,我以Devoxx的身份參加…

java runtime 異常_Java中RuntimeException和Exception

在java的異常類體系中,Error和RuntimeException是非檢查型異常,其他的都是檢查型異常。所有方法都可以在不聲明throws的情況下拋出RuntimeException及其子類不可以在不聲明的情況下拋出非RuntimeException簡單的說,非RuntimeException必要自己寫catch塊處…

BZOJ3130: [Sdoi2013]費用流[最大流 實數二分]

3130: [Sdoi2013]費用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 960 Solved: 505[Submit][Status][Discuss]Description Alice和Bob在圖論課程上學習了最大流和最小費用最大流的相關知識。 最大流問題:給定一張有向圖表示運輸網絡…

Linux Shell 003-變量

Linux Shell 003-變量 本節關鍵字:Linux、Shell、變量、全局變量、系統變量 相關指令:read、echo、unset、export 變量的含義 變量是用來臨時保存數據的,該數據是可以變化的數據。如果某個內容需要多次使用,并且在代碼中重復出現…

Java自動機實現

這篇文章將解決在Java中實現有限狀態機的問題。 如果您不知道什么是FSM或在什么地方可以使用FSM,您可能會熱衷于閱讀此 , 這個和這個 。 如果您發現自己在設計上使用FSM的情況,則可能已經開始為實現相同接口的每個狀態編寫類。 一個好的設計可…

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files這個文件找不到

在C:\Windows\Microsoft.NET\Framework64\v4.0.30319文件夾下面建立Temporary ASP.NET Files 文件夾(Framework64 注意64,這個可能是我們用的64位系統,但是vs2010不分32位還是64位,所以在C:\Windows\Microsoft.NET\Framework\v4.0…

java電腦運行視頻演示_javaweb視頻第一天(二)

無論通過哪種方式得到的class類對象,是同一個。比較的是地址碼這里教會你:如何去使用class對象現在就知道這個:如何使用反射,并且說反射是實現了什么樣的功能。如何通過反射得到里面的相應字段,得到里面的相應函數等等…

模型驅動 ModelDriven

ModelDriven:模型驅動,對所有action的模型對象進行批處理. 我們在開發中, 在action中一般是用實體對象,然后給實體對象get,set方法。 RegAction{   User user ;   //get/set} 然后在jsp頁面中給action中的user屬性綁定值是通過如下方式 &…

本月風味– Neo4j和Heroku

Neo4j今年早些時候發起了一項挑戰,即“ 種子播云 ”,以使人們使用Neo4j附加組件在Heroku上創建模板或演示應用程序。 經過許多內部辯論之后,我決定進入,但由于缺乏想法而陷入絕望。 當我什么都沒做的時候,這個主意就出…

1 + 11 + 1111+ 11111+ ..... + 11111(2016個) 結果是幾位數

# -*- coding: utf-8 -*- """ Created on Mon Mar 21 20:38:06 2016author: yanjie """1 11 1111 11111 ..... 11111(2016個) 結果是幾位數 用什么數據結構 有幾個6 寫算法a []; m 0; six 0; for i in range(2016,0,-1):b (im) % 10;m (…