黄斌
摘要:随着Internet技术的不断发展,使用基于(B/S)浏览器/服务器信息管理平台在现实中应用也越来越广泛,J2ee技术的发展,web系统应用设计与使用越来越复杂,保护web系统资源的合法性,已经成为一个web系统中不可或缺的一部分,使用基于J2ee技术的SSH架构及RBAC模型,借助注解动态代理等相关技术开发,使得权限管理系统的实现更加灵活,低耦合且通用性良好。
关键词: SSH;注解;动态代理;权限管理
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)20-0064-02
The Design of the General Rights Management System Based on SSH Framework
HUANG Bin
(East China Institute of Technology, Nanchang 330013, China)
Abstract:With the continuous development of Internet technology, the use of J2ee (B/S) browser / server information management platform is becoming more and more extensive, the development of web technology, J2ee system application design and use more and more complex, protect web system resources, has become an integral part of web system, using SSH technology based on RBAC model, the use of dynamic proxy and other related technology development, so that the management system is more flexible, low coupling and general purpose.
Key words: SSH; annotation; dynamic proxy; authority management
企业或政府部门,为了便于提高工作效率,不断推动移动互联网的快速发展,基于SSH架构的java web系统开发的应用程序开发越来越广泛,对不同用户进行权限控制,并且权限设计的好坏,直接关系系统的安全性[1]。以往的权限管理系统,有其局限性,注解技术的出现, 从而避免成千上万行的配置文件,降低文件可读性,更专注于代码的编写,动态代理是GOF设计模式中的一种,其作用就是和业务代码不耦合在一起,并将其从业务逻辑中分离出去,将这些核心业务所共同的逻辑代码进行封装,比如权限管理,日志,事务管理。
1 方案设计
1.1权限模型设计
权限管理模块只是实现系统中控制用户对功能的使用情况,在web系统中,使用的每一个功能都对应的URL,对功能的控制就是对URL的访问控制,基于角色权限管理模块就是在用户和权限之间设置了一个新的实体即角色,每一个角色授予对应的功能或URL的集合,角色作为中间媒介把用户集合和权限集合联系起来,用户的权限就是用户所有角色的权限的集合,通过系统分配给用户相应的角色,实现对用户权限的管理[2]。
1.2 SSH框架系统搭建
SSH开发框架是指由struts2+hibernate3+spring3.0开源软件搭建的, java EE企业级的目前流行的一种WEB开发框架,该框架采用经典的J2ee三层架构(表现层,中间层(业务逻辑层)以及数据访问层,在SSH框架中采用了优秀的MVC框架设计模式,其中struts2作为表现层,负责控制业务逻辑层和表现层的交互,作用用来调用业务逻辑层,并将业务数据返回给表现层,然后组织展现,而Spring作为SSH框架的核心,其作用贯穿了整个中间层,将展现层,业务逻辑层,数据层以及实体对象无缝整合,数据访问层采用hibernate作为ORM框架,通过实体关系映射工具JPA将关系数据库的数据映射成对象,很方便地实现以面向对象方式操作数据库,数据访问层主要负责与实体对象的交互,该层封装了数据的增,删,改,查的操作,整个SSH框架采用全注解的方法搭建,与传统的SSH框架相比,无需配置文件,实现方式更加简单,开发效率更高在基于SSH(struts+hibernate+spring)框架三层开发模式中,业务层只专注于业务逻辑代码的编写,不关心表现层或者数据访问层,各尽其职,而往往这些业务功能就代表一个功能,在系统管理中,除了实现相关的业务功能的同时,一个业务功能就相对应一个操作权限,对应一个资源,对应一个URL地址,需要在设计时去满足不同用户的需求,在使用系统时,那些角色具有的资源,达到控制那些用户具有相应的访问权限在显示层,只体现该功能是否可以操作,或者展示给用户是否能进行相应的操作,数据访问层,仅仅只是单纯的对数据进行相关的增删改查的操作,在业务代码中,往往需要增加些额外的功能比如日志管理,权限管理等,如果把具有权限逻辑判断的代码嵌入进业务层中,不利于系统的维护和扩展,这种硬编码的方式会导致大量的重复的代码的出现,也不利于各个模块的重用,为了避免上述问题的出现,在设计系统的时候,往往把与业务无关的代码进行抽取,抽取成相应的公共方法,这样避免了代码的臃肿,这也满足OOAD相关的设计原则,但是缺乏灵活性,可扩展性,维护性而借助于java提供的动态代理技术,结合注解技术实现权限控制,可以解决以上的问题。
2 核心技术
2.1 注解
随着企业端软件应用越来越复杂,配置文件内容越来越多,导致配置文件冗余,使得可读性变差,为了解决程序配置可读性问题, jdk1.5推出的一项技术——注解(Annotation),其顾名思义为注释,解释。但从功能上却不仅仅是注释那么简单,浅显的理解注解其实就是代码里的特殊标记, 注解相当于代码中配置文件,其目的就是减少在xml文件的配置,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行,注解单一的工作不能发挥其作用,必须同时需要结合反射技术一起使用,在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类 注解程序开发流程。
2.1.1注解类实现
使用@interface 定义所有注解类都默认继承 java.lang.annotation.Annotation 接口在一个类 应用注解类,通过反射技术获得注解信息通过java.lang.reflect.AnnotatedElement 在程序运行时 获得注解信息。
2.2 动态代理
java动态代理在jdk1.2出现的技术,代理模式有分静态代理以及动态代理,代理模式是常用的java设计模式,当.class文件 被类加载器加载到内存形成Class对象,所有程序访问都是针对Class对象 ,动态代理技术可以根据Class对象的实现接口,在内存中虚拟构造一个对象,该对象成为代理对象,访问真实对象的所有API的过程中 都将通过代理对象去访问。动态代理的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。动态代理的原理如图1所示。
图1 动态代理原理
2.2.1实现动态代理的两个核心方法
实现InvocationHandler接口在该接口中唯一定义了一个方法invoke(Object obj,Method method,Object[] args) 该接口是我们需要去实现的,其中该方法中三个参数分别代表。
a)参数obj代表需要代理类;
b)method代表被代理的方法;
c)args代表被代理的方法的参数数组
java提供了一个Proxy类,调用它的静态方法Proxy.newProxyInstance(obj.getClass()
.getClassLoader(),Obj.getClass.getInstances(),this)方法可以生成某个对象的代理对象,使用该方法生成代理对象时,该方法有三个参数,三个参数分别是:
a)生成代理对象使用哪个类装载器;
b)生成哪个对象的代理对象,通过接口指定;
c)生成的代理对象的方法里;
2.2.2权限管理的实现
在基于mvc设计模式的J2ee开发模式中,service层专注于业务代码逻辑的编写,如果把具有权限逻辑判断的代码嵌入进业务层中,不利于系统的维护和扩展,这种硬编码的方式会导致大量的重复的代码的出现,也不利于各个模块的重用而借助于java提供的动态代理技术,可以解决以上的问题,结合注解技术实现权限控制。
在系统中,应用程序中有Privilegeinfo,OperateService,ServiceFactory三个主要核心类, 其中serviceFactory进行权限判断
/*当前注解用于配置用户的权限信息*/
public @interface Privilegeinfo {
String value();}
public class OperateService {
/*根据该用户id获取其拥有的权限*/
public List
OperateDao operateDao = new OperateDaoImpl();
List
return privileges;}}
/* 该业务工厂类用于利用动态代理技术读取当前用户是否具有对应的业务权限*/
public class ServiceFactory {
//该方法用于利用动态代理读取权限.
public static OperateService getOperateService(final Userinfo userinfo){
OperateService proxyService = (OperateService);
Proxy.newProxyInstance(OperateService.class.getClassLoader(), OperateServiceImpl.class.getInterfaces(), new InvocationHandler() {
//invoke()方法用于通过反射技术读取对应业务方法的权限信息
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Privilegeinfo privilege = method.getAnnotation(Privilegeinfo.class);
// 获取对应业务方法的权限信息
String privilegeinfo = privilege.value();
// 获取当前用户的权限信息(查询数据库表,这里需要用户user_id信息)
......
// 判断当前用户是否具有对应的权限信息
for (String privilegeValue : privileges) {
if(privilegeinfo.equals(privilegeValue)){
return "success";}// 如果具有
}// 如果没有
return "error";}
});
return proxyService; //返回业务代理类
}}
3 结束语
利用Java动态代理技术实现权限系统的控制,能够有效减少降低业务逻辑和权限代码的耦合,进一步减少代码量,减少工作量,提高程序的可扩展性,可维护性,在实际的web系统的开发过程中,可以根据本文提出的原理和实例,定义具体的handler接口的实现,当Invocation-Handler被触发,调用相应的handler进行处理。
参考文献:
[1] 韩江. 基于SSH架构的Java Web通用权限管理的设计[J]. 智能计算机与应用, 2014(4):52-54.
[2] 牛牧, 刘丽, 祝建中. 基于JAVA动态代理的事务处理[J]. 科技广场, 2007(3):159-161.