一、使用反射动态添加权限
在该系统中,我使用struts2的时候非常规范,访问的Action的形式都是"ActionClassName_MethodName.action?参数列表",所以可以非常方便的使用反射初始化权限表。
比较关键的是获取所有Action类所在的包的方法:
URL url=ClassLoader.getSystemResource("com/kdyzm/struts/action"); File dir=new File(url.toURI());
然后获取所有文件(有不是class后缀名的文件):
File[] fiels=dir.listFiles();
接下来遍历文件列表,获取文件名即可获取Action名字,之后就是反射的问题了,略,详细代码:
1 package com.kdyzm.init; 2 3 import java.io.File; 4 import java.lang.reflect.Method; 5 import java.net.URL; 6 7 import org.springframework.context.ApplicationContext; 8 import org.springframework.context.support.ClassPathXmlApplicationContext; 9 import com.kdyzm.domain.security.Right; 10 import com.kdyzm.service.RightService; 11 public class InitRight { 12 public static void main(String[] args) throws Exception { 13 ApplicationContext context=new ClassPathXmlApplicationContext("spring/applicationContext.xml"); 14 RightService rightService=(RightService) context.getBean("rightService"); 15 16 // InitRight.class.getClassLoader(); 17 URL url=ClassLoader.getSystemResource("com/kdyzm/struts/action"); 18 File dir=new File(url.toURI()); 19 File[] fiels=dir.listFiles(); 20 for(File file:fiels){ 21 if(file.getName().endsWith("class")) 22 processClass(file,rightService); 23 } 24 System.out.println("完成初始化任务!"); 25 } 26 private static void processClass(File file, RightService rightService) throws Exception { 27 String basePackage="com.kdyzm.struts.action."; 28 String className=basePackage+file.getName().substring(0,file.getName().indexOf(".")); 29 Class clazz=Class.forName(className); 30 Method[]methods=clazz.getDeclaredMethods(); 31 String methodName=""; 32 Class returnType=null; 33 Class[] parameters=null; 34 String url=""; 35 for(Method method:methods){ 36 methodName=method.getName(); 37 returnType=method.getReturnType(); 38 parameters=method.getParameterTypes(); 39 if(returnType.equals(String.class) 40 &&(parameters==null||parameters.length==0)){ 41 url="/"+file.getName().substring(0,file.getName().indexOf("."))+"_"+methodName+".action"; 42 Right right=new Right(); 43 right.setRightUrl(url); 44 rightService.saveOrUpateRight(right); 45 } 46 } 47 } 48 }
二、使用权限拦截器动态添加权限
这是为了方便在开发阶段使用的方法,在实际使用的时候需要将该拦截器去掉。
这里涉及到一个技术点,即如何获取ApplicationConext对象,spring容器也在application作用域中,所以如果想要获取ApplicationContext对象,一定要获取ServletContext,通过WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)方法就能够获取ApplicationContext了。
1 package com.kdyzm.struts.interceptors; 2 3 import javax.servlet.ServletContext; 4 5 import org.apache.struts2.ServletActionContext; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.web.context.support.WebApplicationContextUtils; 8 9 import com.kdyzm.service.RightService; 10 import com.opensymphony.xwork2.ActionInvocation; 11 import com.opensymphony.xwork2.ActionProxy; 12 import com.opensymphony.xwork2.interceptor.Interceptor; 13 /** 14 * 该拦截在发布之后应当删除掉 15 * @author kdyzm 16 * 17 */ 18 public class CatchUrlInterceptor implements Interceptor{ 19 private static final long serialVersionUID = 6747245610234756713L; 20 21 @Override 22 public void destroy() { 23 System.out.println("捕获URL拦截器被销毁!"); 24 } 25 26 @Override 27 public void init() { 28 System.out.println("捕获URL拦截器初始化!"); 29 } 30 @Override 31 public String intercept(ActionInvocation invocation) throws Exception { 32 ActionProxy actionProxy=invocation.getProxy(); 33 String namespace=actionProxy.getNamespace(); 34 String actionName=actionProxy.getActionName(); 35 if(namespace==null||"/".equals(namespace)){ 36 namespace=""; 37 } 38 String url=namespace+"/"+actionName; 39 ServletContext sc=ServletActionContext.getServletContext(); 40 ApplicationContext context=WebApplicationContextUtils.getWebApplicationContext(sc); 41 RightService rightService=(RightService) context.getBean("rightService"); 42 rightService.appendRightByUrl(url+".action"); 43 return invocation.invoke(); 44 } 45 }
struts.xml文件中的配置:
1 <interceptors> 2 <interceptor name="loginInterceptor" class="com.kdyzm.struts.interceptors.LoginInterceptor"></interceptor> 3 <interceptor name="catchUrlInterceptor" class="com.kdyzm.struts.interceptors.CatchUrlInterceptor"></interceptor> 4 <interceptor-stack name="surveyparkStack"> 5 <interceptor-ref name="loginInterceptor"></interceptor-ref> 6 <!-- url捕获拦截器应当放到登录拦截器之后,完成项目之后应当将该拦截器拿掉 --> 7 <interceptor-ref name="catchUrlInterceptor"></interceptor-ref> 9 <interceptor-ref name="defaultStack"> 11 <param name="modelDriven.refreshModelBeforeResult">true</param> 12 </interceptor-ref> 13 </interceptor-stack> 14 </interceptors> 15 <!-- 定义默认栈 --> 16 <default-interceptor-ref name="surveyparkStack"></default-interceptor-ref>
三、删除权限和修改权限略
修改权限和增加权限使用的是同一个页面,对应的dao中的实现使用的是saveOrUpdate方法,其它略。