本文共 7462 字,大约阅读时间需要 24 分钟。
权限控制是每一个系统都应该有的一个功能,有些只需要简单控制一下就可以了,然而有些却需要进行更加深入和细致的权限控制,尤其是对于一些MIS类系统,基于方法的权限控制就更加重要了。
用反射和自定义注解来实现基于struts2的方法级别的权限控制的主要思想是这样的。
1、先定义一个用于识别在进行action调用的时候标注该方法调用是否需要权限控制,需要什么样的权限的注解类。该注解类一般会包括两个属性,一个是需要的权限,一个是对应的action模块。2、然后就是在需要进行权限控制的action方法上加上该注解类,并标明其应该拥有的权限和对应的action。这样一来在进行action调用的时候可以实现一个自己定义的interceptor来拦截所有的请求,这样在拦截到请求的时候就可以通过ActionInvocation获取到对应的action类的类文件和对应请求的方法名称,然后利用反射来取得action类文件里面对应的请求方法Method,这样就可通过该Method来判断其是否拥有对应的权限控制注解,即看其是否需要进行权限控制,如果需要进行权限控制,就取得该注解并取得其对应的action名称和需要的权限,然后通过session取得当前的用户,并判断当前用户是否拥有对应的某种权限,如果其拥有该权限则继续往下执行,否则,转到自己处理无权限的机制上去。
下面是一段示例代码:
1、定义一个注解,权限配置
package cn.sigangjun.struts2;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 定义一个注解,权限配置 * * @author sigangjun * */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Authority { /** 模块 */ String module(); /** 权限值 */ String privilege();}2、用于拦截请求判断是否拥有权限的拦截器AuthorityInterceptor
package cn.sigangjun.struts2;import java.lang.reflect.Method;import java.text.SimpleDateFormat;import java.util.Date;import org.apache.log4j.Logger;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;/** * 用于拦截请求判断是否拥有权限的拦截器 * * @author sigangjun * */@SuppressWarnings("serial")public class AuthorityInterceptor extends AbstractInterceptor { private static final Logger logger = Logger.getLogger(AuthorityInterceptor.class); public String intercept(ActionInvocation invocation) throws Exception { String methodName = invocation.getProxy().getMethod(); Class clazz = invocation.getAction().getClass(); // 获取类对象 Method currentMethod = clazz.getMethod(methodName); // 检查Action类AnnotationTest是否含有@Authority注解 if (currentMethod.isAnnotationPresent(Authority.class)) { // 从session里取得当前的用户 String currentUser = (String) ServletActionContext.getRequest().getSession().getAttribute("currentUser"); // 取得权限验证的注解 Authority authority = currentMethod.getAnnotation(Authority.class); // 取得当前请求的注解的action String module = authority.module(); // 取得当前请求需要的权限 String privilege = authority.privilege(); /** * 然后可以在此判断当前用户是否拥有对应的权限,如果没有可以跳到指定的无权限提示页面, 如果拥有则可以 继续往下执行。 if (拥有对应的权限) { return invocation.invoke(); } else { return "无权限"; } */ logger.warn("++++++++++++++++++++++++++++++++++++++++++++++++++++++"); logger.warn("用户[" + currentUser + "]在" + new SimpleDateFormat("yyyy-MM-dd hh24:mm:ss").format(new Date()) + "调用了[" + clazz.getName() + "]类的[" + methodName + "]方法,所在模块[" + module + "],拥有权限[" + privilege + "]。"); logger.warn("++++++++++++++++++++++++++++++++++++++++++++++++++++++"); } return invocation.invoke(); }}
3、需要进行权限控制的Action
package cn.sigangjun.struts2;import org.apache.struts2.convention.annotation.Action;import org.apache.struts2.convention.annotation.Namespace;import org.apache.struts2.convention.annotation.Result;import org.apache.struts2.convention.annotation.Results;import org.apache.struts2.convention.annotation.InterceptorRef;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;/** * 请求Action * @author sigangjun * */@SuppressWarnings("serial")@Namespace(value = "/user")@Results(value = { @Result(name = "success", location = "/index.jsp"), @Result(name = "add", location = "/add.jsp"), })@Action(value = "action") //默认为:AnnotationAction-->annotation//@Action(value = "test")//@Action(value = "/admin/top-set/save", interceptorRefs = {// @InterceptorRef(value = "fileUpload", params = { "allowedExtensions", "jpg,png,gif" }),// @InterceptorRef(value = "crudStack"), // })public class AnnotationAction extends ActionSupport { // 访问路径:http://localhost:8080/02struts2/action!list.htm @Authority(module = "annotation", privilege = "list") public String list() throws Exception { ActionContext.getContext().getSession().put("currentUser", "uuu"); System.out.println("-------execute---------"); return SUCCESS; } // 访问路径:http://localhost:8080/02struts2/action!add.htm @Authority(module = "annotation", privilege = "add") public String add() { System.out.println("-------test---------"); return "add"; }}
4、在struts2的配置文件里面配置自定义的权限控制拦截器
5、log4j.properties
log4j.rootCategory=INFO, stdout , R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender log4j.appender.R.File=D:\\logs\\qc.log log4j.appender.R.layout=org.apache.log4j.PatternLayout 1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n log4j.logger.com.neusoft=DEBUG log4j.logger.com.opensymphony.oscache=ERROR log4j.logger.net.sf.navigator=ERROR log4j.logger.org.apache.commons=ERROR log4j.logger.org.apache.struts=WARN log4j.logger.org.displaytag=ERROR log4j.logger.org.springframework=DEBUG log4j.logger.com.ibatis.db=WARN log4j.logger.org.apache.velocity=FATAL log4j.logger.com.canoo.webtest=WARN log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN log4j.logger.org.hibernate=DEBUG log4j.logger.org.logicalcobwebs=WARN log4j.rootCategory=INFO, stdout , Rlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.R.File=D:\\logs\\qc.loglog4j.appender.R.layout=org.apache.log4j.PatternLayout1log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%nlog4j.logger.com.neusoft=DEBUGlog4j.logger.com.opensymphony.oscache=ERRORlog4j.logger.net.sf.navigator=ERRORlog4j.logger.org.apache.commons=ERRORlog4j.logger.org.apache.struts=WARNlog4j.logger.org.displaytag=ERRORlog4j.logger.org.springframework=DEBUGlog4j.logger.com.ibatis.db=WARNlog4j.logger.org.apache.velocity=FATALlog4j.logger.com.canoo.webtest=WARNlog4j.logger.org.hibernate.ps.PreparedStatementCache=WARNlog4j.logger.org.hibernate=DEBUGlog4j.logger.org.logicalcobwebs=WARN
5、 web.xml
struts2 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter struts2 /* index.jsp
5、pom.xml
4.0.0 cn.sigangjun 02struts2 war 0.0.1-SNAPSHOT 02struts2 Maven Webapp http://maven.apache.org org.apache.struts struts2-core 2.3.4.1 org.apache.struts struts2-convention-plugin 2.3.4.1 junit junit 4.10 test log4j log4j 1.2.17 02struts2
转载地址:http://qdnni.baihongyu.com/