码迷,mamicode.com
首页 > 其他好文 > 详细

SSH系列:(16)角色-权限管理(后台)

时间:2016-08-19 06:23:20      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:ssh


1、角色和权限的关系

系统中可以存在多个角色每个角色可以自由的组合系统定义的权限集合,即角色权限的关系是多对多的关系。为了保存这种多对多关系,需要一个“角色权限表”来保存。

角色权限的多对多关系,可以进行拆分:“角色”与“角色权限”的关系“权限”和“角色权限”的关系。“角色”与“角色权限”的关系是一对多的关系;而“权限”与“角色权限”的关系也是一对多的关系。



这里的特殊之处是:由于系统的权限的数目比较少,以常量的形式存储于类文件中,因此不存在“权限”表;而“角色”和“角色权限”是需要保存的,因而需要“角色表”和“角色权限表”,所以进行的操作,则是维护“角色表”和“角色权限表”之间一对多的关系。



将系统中需要使用到的权限定义出来(PrivilegeStatics类):粗粒度的分配各个子系统的访问权限;这些权限可以定义在常量文件中。


package com.rk.core.constant;

import java.util.HashMap;
import java.util.Map;

public class PrivilegeStatics {
	/*----------------------系统权限集合--------------------------*/
	public static String PRIVILEGE_XZGL = "xzgl"; 
	public static String PRIVILEGE_HQFW = "hqfw"; 
	public static String PRIVILEGE_ZXXX = "zxxx"; 
	public static String PRIVILEGE_NSFW = "nsfw"; 
	public static String PRIVILEGE_SPACE = "spaces"; 

	public static Map<String, String> PRIVILEGE_MAP;
	static {
		PRIVILEGE_MAP = new HashMap<String, String>();
		PRIVILEGE_MAP.put(PRIVILEGE_XZGL, "行政管理");
		PRIVILEGE_MAP.put(PRIVILEGE_HQFW, "后勤服务");
		PRIVILEGE_MAP.put(PRIVILEGE_ZXXX, "在线学习");
		PRIVILEGE_MAP.put(PRIVILEGE_NSFW, "纳税服务");
		PRIVILEGE_MAP.put(PRIVILEGE_SPACE, "我的空间");
	}
}


2、entity->dao->service->action->config


2.1、实体类和映射文件(*.hbm.xml)


Role.java 

由于“角色”与“角色权限”之间是一对多的关系,因此Role实体类中包含Set<RolePrivilege> rolePrivileges对象。

package com.rk.tax.entity;

import java.io.Serializable;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;

public class Role implements Serializable {
	private String roleId;
	private String name;
	private String state;
	private Set<RolePrivilege> rolePrivileges;
	
	//角色状态
	public static String ROLE_STATE_VALID = "1";//有效
	public static String ROLE_STATE_INVALID = "0";//无效
	
	
	
	public Role() {
	}
	public Role(String roleId) {
		this.roleId = roleId;
	}
	public String getRoleId() {
		return roleId;
	}
	public void setRoleId(String roleId) {
		this.roleId = roleId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
	public Set<RolePrivilege> getRolePrivileges() {
		return rolePrivileges;
	}
	public void setRolePrivileges(Set<RolePrivilege> rolePrivileges) {
		this.rolePrivileges = rolePrivileges;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj) return true;
		if(obj == null) return false;
		if(this.getClass() != obj.getClass()) return false;
		
		Role other = (Role) obj;
		if(!StringUtils.equals(this.roleId, other.roleId)) return false;
		if(!StringUtils.equals(this.name, other.name)) return false;
		if(!StringUtils.equals(this.state, other.state)) return false;
		
		return true;
	}
	
	
}

Role.hbm.xml

注意:在对rolePrivileges属性进行映射的时候,它的inverse属性为true,表示“在操作Role对象时,不会对角色表 和 角色权限表 之间的关系进行映射”,lazy="false"表示不使用懒加载,cascade="save-update,delete"表示进行级联的保存、更新和删除(换句话说,如果保存Role对象时,如果rolePrivileges有值,也会保存相应的RolePrivilege对象;有一点,我很在意,就是在删除的时候,它是否能够级联删除呢?在我印象中,是不能删除的。我是这样理解的:虽然很多人都在说cascade和inverse之间没有关系,而我认为cascade要优先于inverse。如果不能进行删除,我想可能是因为Role没有办法解除两者之间的关系。如果能够删除,则表示我猜测错误了。)。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.tax.entity" auto-import="true">
	<class name="Role" table="T_Roles">
		<id name="roleId" column="role_id" type="string" length="32">
			<generator class="uuid.hex"></generator>
		</id>
		<property name="name" column="name" type="string" length="20" not-null="true"></property>
		<property name="state" column="state" type="string" length="1"></property>
		<set name="rolePrivileges" inverse="true" lazy="false" cascade="save-update,delete">
			<key column="role_id"></key>
			<one-to-many class="RolePrivilege"/>
		</set>
	</class>

</hibernate-mapping>

RolePrivilege.java,它表示“角色权限表”,而这里的特殊之处,就是它没有直接存储两个属性,而是使用了一个类来代表一个共同主键。

package com.rk.tax.entity;

public class RolePrivilege {
	private RolePrivilegeId id;

	public RolePrivilege() {
	}

	public RolePrivilege(RolePrivilegeId id) {
		this.id = id;
	}

	public RolePrivilegeId getId() {
		return id;
	}

	public void setId(RolePrivilegeId id) {
		this.id = id;
	}
	
}

RolePrivilegeId.java ,在这里需要注意的是它存储的属性是Role类型的变量role,而不是String类型的变量role_id。在这里回顾一下Role.java中定义了Set<RolePrivilege> rolePrivileges属性,也就是说Role类对象中可以直接(由于映射文件中设置了lazy="false")查看Role拥有的“角色权限”信息,而这里保存Role类型的role对象,这样做的目的是,我们能够通过RolePrivilege对象直接找到它所属于的角色信息。

package com.rk.tax.entity;

import java.io.Serializable;

import org.apache.commons.lang3.StringUtils;

public class RolePrivilegeId implements Serializable {
	private Role role;
	private String code;
	
	public RolePrivilegeId() {
	}
	
	public RolePrivilegeId(Role role, String code) {
		this.role = role;
		this.code = code;
	}

	public Role getRole() {
		return role;
	}
	public void setRole(Role role) {
		this.role = role;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((code == null) ? 0 : code.hashCode());
		return result;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;
		if (obj == null) return false;
		if (this.getClass() != obj.getClass()) return false;
			
		RolePrivilegeId other = (RolePrivilegeId) obj;
		if(!StringUtils.equals(this.code, other.code)) return false;

		if (this.role == null && other.role != null) {
			return false;
		} else if (!this.role.equals(other.role)){
			return false;
		}
			
		return true;
	}
	
}

RolePrivilege.hbm.java

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.tax.entity" auto-import="true">
	<class name="RolePrivilege" table="R_Role_Privilege">
		<composite-id name="id" class="RolePrivilegeId">
			<key-many-to-one name="role" column="role_id" lazy="false" class="Role"></key-many-to-one>
			<key-property name="code" column="code" type="string" length="20"></key-property>
		</composite-id>
	</class>
</hibernate-mapping>


2.2、dao层

这里只有RoleDao,基于的操作是继承于BaseDao<Role>对象,而它只有一个方法deleteRolePrivilegeByRoleId,是通过roleId来删除相应的角色权限信息。

RoleDao.java

package com.rk.tax.dao;

import com.rk.core.dao.BaseDao;
import com.rk.tax.entity.Role;

public interface RoleDao  extends BaseDao<Role>{
	void deleteRolePrivilegeByRoleId(String roleId);
}

RoleDaoImpl.java 

package com.rk.tax.dao.impl;

import org.hibernate.Query;

import com.rk.core.dao.impl.BaseDaoImpl;
import com.rk.tax.dao.RoleDao;
import com.rk.tax.entity.Role;

public class RoleDaoImpl extends BaseDaoImpl<Role> implements RoleDao {

	public void deleteRolePrivilegeByRoleId(String roleId) {
		Query query = getSession().createQuery("delete from RolePrivilege where id.role.roleId=?");
		query.setParameter(0, roleId);
		query.executeUpdate();
	}

}


2.3、service层

RoleService.java

package com.rk.tax.service;

import java.io.Serializable;
import java.util.List;

import com.rk.tax.entity.Role;

public interface RoleService {
	//新增
	public void save(Role entity);
	//更新
	public void update(Role entity);
	//根据id删除
	public void delete(Serializable id);
	//根据id查找
	public Role findById(Serializable id);
	//查找列表
	public List<Role> findAll();
}

RoleServiceImpl.java

package com.rk.tax.service.impl;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.rk.tax.dao.RoleDao;
import com.rk.tax.entity.Role;
import com.rk.tax.service.RoleService;

@Service("roleService")
public class RoleServiceImpl implements RoleService {
	@Resource
	private RoleDao roleDao;
	
	public void save(Role entity) {
		roleDao.save(entity);
	}

	public void update(Role entity) {
		//1、删除该角色对应的所有权限
		roleDao.deleteRolePrivilegeByRoleId(entity.getRoleId());
		//2、更新角色及其权限
		roleDao.update(entity);
	}

	public void delete(Serializable id) {
		roleDao.delete(id);
	}

	public Role findById(Serializable id) {
		return roleDao.findById(id);
	}

	public List<Role> findAll() {
		
		return roleDao.findAll();
	}
}


2.4、action层

RoleAction.java

package com.rk.tax.action;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionContext;
import com.rk.core.action.BaseAction;
import com.rk.core.constant.PrivilegeStatics;
import com.rk.tax.entity.Role;
import com.rk.tax.entity.RolePrivilege;
import com.rk.tax.entity.RolePrivilegeId;
import com.rk.tax.service.RoleService;

@Controller("roleAction")
@Scope("prototype")
public class RoleAction extends BaseAction {
	/***** 1、业务数据 *****/
	private List<Role> roleList;
	private Role role;
	private String[] privilegeIds;
	
	/***** 2、业务实现类 *****/
	@Resource
	private RoleService roleService;

	/***** 3、页面响应操作 *****/
	//列表页面
	public String listUI(){
		//加载权限集合
		ActionContext.getContext().getContextMap().put("privilegeMap", PrivilegeStatics.PRIVILEGE_MAP);
		roleList = roleService.findAll();
		return "listUI";
	}
	
	//跳转到新增页面
	public String addUI(){
		//加载权限集合
		ActionContext.getContext().getContextMap().put("privilegeMap", PrivilegeStatics.PRIVILEGE_MAP);
		return "addUI";
	}
	
	//保存新增
	public String add(){
		if(role != null){
			//处理权限保存
			if(privilegeIds != null){
				Set<RolePrivilege> set = new HashSet<RolePrivilege>();
				for(int i=0;i<privilegeIds.length;i++){
					set.add(new RolePrivilege(new RolePrivilegeId(role, privilegeIds[i])));
				}
				role.setRolePrivileges(set);
			}
			roleService.save(role);
		}
		return "list";
	}
	
	//跳转到编辑页面
	public String editUI(){
		//加载权限集合
		ActionContext.getContext().getContextMap().put("privilegeMap", PrivilegeStatics.PRIVILEGE_MAP);
		if(role != null && role.getRoleId()!=null){
			role = roleService.findById(role.getRoleId());
			//处理回显
			if(role.getRolePrivileges() != null && role.getRolePrivileges().size()>0){
				privilegeIds = new String[role.getRolePrivileges().size()];
				int i = 0;
				for(RolePrivilege rp : role.getRolePrivileges()){
					privilegeIds[i] = rp.getId().getCode();
				}
			}
		}
		return "editUI";
	}
	
	//保存编辑
	public String edit(){
		if(role != null){
			//处理权限保存
			if(privilegeIds != null){
				Set<RolePrivilege> set = new HashSet<RolePrivilege>();
				for(int i=0;i<privilegeIds.length;i++){
					set.add(new RolePrivilege(new RolePrivilegeId(role, privilegeIds[i])));
				}
				role.setRolePrivileges(set);
			}
			roleService.update(role);
		}
		return "list";
	}
	
	//删除
	public String delete(){
		if(role != null && role.getRoleId() != null){
			roleService.delete(role.getRoleId());
		}
		return "list";
	}
	
	//批量删除
	public String deleteSelected(){
		if(selectedRow != null){
			for(String id : selectedRow){
				roleService.delete(id);
			}
		}
		return "list";
	}


	
	// {{
	public List<Role> getRoleList() {
		return roleList;
	}

	public void setRoleList(List<Role> roleList) {
		this.roleList = roleList;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public String[] getPrivilegeIds() {
		return privilegeIds;
	}

	public void setPrivilegeIds(String[] privilegeIds) {
		this.privilegeIds = privilegeIds;
	}	
	// }}
}


2.5、config


2.5.1、entity层配置

就是对实体类进行hibernate的映射,即*.hbm.xml文件


2.5.2、dao层配置

就是将dao注入到spring 的IOC容器中

bean-dao.xml (注意,在这里没有使用Annotation的方式,是因为它有一个parent属性,对于这一点,我查了查,目前超过自己的知识范围,看不太懂,而之后的service、action都使用Annotation的方式注入到spring的容器中。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
     	http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

	<bean id="userDao" class="com.rk.tax.dao.impl.UserDaoImpl" parent="baseDao"></bean>
	<bean id="roleDao" class="com.rk.tax.dao.impl.RoleDaoImpl" parent="baseDao"></bean>

</beans>


2.5.3、service层

就是将service注入到spring的IOC容器当中

bean-service.xml这里去掉了之前的注册方式,而是使用注解扫描。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
     	http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 开启注解扫描 -->
	<context:component-scan base-package="com.rk.tax.service.impl"></context:component-scan>

</beans>


2.5.4、action层

action设置到注册到spring和struts当中。

bean-action.xml 使用注解方式对bean进行注册的方便之处,就是假如UserAction当中涉及到了UserService和RoleService,我们只需要在两个类型的变量上添加@Resource就可以完成注册,而不需要修改spring的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
     	http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 开启注解扫描 -->
	<context:component-scan base-package="com.rk.tax.action"></context:component-scan>
</beans>


struts-role.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<package name="role_package" namespace="/tax" extends="base-default">
		<action name="role_*" class="roleAction" method="{1}">
			<result name="{1}">/WEB-INF/jsp/tax/role/{1}.jsp</result>
			<result name="list" type="redirectAction">
				<param name="actionName">role_listUI</param>
			</result>
		</action>
	</package>
</struts>



SSH系列:(16)角色-权限管理(后台)

标签:ssh

原文地址:http://lsieun.blog.51cto.com/9210464/1840147

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!