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.mzph.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 (…