今天刚学习了通过自定义注解+拦截器实现权限控制,自己花了点时间整理,发到网站同网友交流分享。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 自定义注解
* @author grace
*
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Limit{
String module(); //模块名称
String privilege(); //操作名称
}
#权限组表
CREATE TABLE `sys_role` (
`id` varchar(36), #编号
`remark` TEXT, #备注
`name` VARCHAR(100) DEFAULT NULL, #名称
PRIMARY KEY (`id`)
)
#操作表
CREATE TABLE sys_popedom
(
popedomModule VARCHAR(30), #模块名称
popedomPrivilege VARCHAR(30), #操作名称
sort INTEGER(11), #排序
title VARCHAR(200), #提示
popedomName VARCHAR(200), #标题
remark TEXT, #说明
PRIMARY KEY(popedomModule,popedomPrivilege)
)
#操作权限表
CREATE TABLE sys_popedom_privilege
(
roleId VARCHAR(36), #权限组编号
popedomModule VARCHAR(30), #模块名称
popedomPrivilege VARCHAR(30), #操作名称
PRIMARY KEY(roleId,popedomModule,popedomPrivilege)
)
/*
* SysRole:权限组表
*/
@SuppressWarnings("serial")
public class SysRole implements java.io.Serializable {
private String id;
private String name;
private String remark;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
/*
* 操作表
*/
@SuppressWarnings("serial")
public class SysPopedom implements java.io.Serializable{
/*
* CREATE TABLE sys_popedom
(
popedomModule VARCHAR(30), #模块名称
popedomPrivilege VARCHAR(30), #操作名称
sort INTEGER(11), #排序
title VARCHAR(200), #提示
popedomName VARCHAR(200), #标题
remark TEXT, #说明
PRIMARY KEY(popedomModule,popedomPrivilege)
)
*/
private SysPopedomId id;//主键 OID
private Integer sort;
private String title;
private String popedomName;
private String remark;
public SysPopedomId getId() {
return id;
}
public void setId(SysPopedomId id) {
this.id = id;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPopedomName() {
return popedomName;
}
public void setPopedomName(String popedomName) {
this.popedomName = popedomName;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}
/**
* 操作表中的联合主键类
* @author grace
*
*/
@SuppressWarnings("serial")
public class SysPopedomId implements java.io.Serializable {
private String popedomModule;
private String popedomPrivilege;
public String getPopedomModule() {
return popedomModule;
}
public void setPopedomModule(String popedomModule) {
this.popedomModule = popedomModule;
}
public String getPopedomPrivilege() {
return popedomPrivilege;
}
public void setPopedomPrivilege(String popedomPrivilege) {
this.popedomPrivilege = popedomPrivilege;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((popedomModule == null) ? 0 : popedomModule.hashCode());
result = prime
* result
+ ((popedomPrivilege == null) ? 0 : popedomPrivilege.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final SysPopedomId other = (SysPopedomId) obj;
if (popedomModule == null) {
if (other.popedomModule != null)
return false;
} else if (!popedomModule.equals(other.popedomModule))
return false;
if (popedomPrivilege == null) {
if (other.popedomPrivilege != null)
return false;
} else if (!popedomPrivilege.equals(other.popedomPrivilege))
return false;
return true;
}
}
/**
* 操作权限表
* @author grace
*
*/
@SuppressWarnings("serial")
public class SysPopedomPrivilege implements java.io.Serializable {
/*
* CREATE TABLE sys_popedom_privilege
* (
* roleId VARCHAR(36), #权限组编号
* popedomModule VARCHAR(30), #模块名称
* popedomPrivilege VARCHAR(30), #操作名称
* PRIMARY KEY(roleId,popedomModule,popedomPrivilege)
* )
*/
private SysPopedomPrivilegeId id;
public SysPopedomPrivilegeId getId() {
return id;
}
public void setId(SysPopedomPrivilegeId id) {
this.id = id;
}
}
/**
* 操作权限表的联合主键类
* @author grace
*
*/
@SuppressWarnings("serial")
public class SysPopedomPrivilegeId implements java.io.Serializable {
private String roleId;
private String popedomModule;
private String popedomPrivilege;
public String getRoleId() {
return roleId;
}
public void setRoleId(String roleId) {
this.roleId = roleId;
}
public String getPopedomModule() {
return popedomModule;
}
public void setPopedomModule(String popedomModule) {
this.popedomModule = popedomModule;
}
public String getPopedomPrivilege() {
return popedomPrivilege;
}
public void setPopedomPrivilege(String popedomPrivilege) {
this.popedomPrivilege = popedomPrivilege;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((popedomModule == null) ? 0 : popedomModule.hashCode());
result = prime
* result
+ ((popedomPrivilege == null) ? 0 : popedomPrivilege.hashCode());
result = prime * result + ((roleId == null) ? 0 : roleId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final SysPopedomPrivilegeId other = (SysPopedomPrivilegeId) obj;
if (popedomModule == null) {
if (other.popedomModule != null)
return false;
} else if (!popedomModule.equals(other.popedomModule))
return false;
if (popedomPrivilege == null) {
if (other.popedomPrivilege != null)
return false;
} else if (!popedomPrivilege.equals(other.popedomPrivilege))
return false;
if (roleId == null) {
if (other.roleId != null)
return false;
} else if (!roleId.equals(other.roleId))
return false;
return true;
}
}
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
/**
* 自定义拦截器
* @author grace
*
*/
@SuppressWarnings("serial")
public class LimitInterceptor extends MethodFilterInterceptor{
public String doIntercept(ActionInvocation invocation) throws Exception {
//获取请求的action对象
Object action=invocation.getAction();
//获取请求的方法的名称
String methodName=invocation.getProxy().getMethod();
//获取action中的方法的封装类(action中的方法没有参数)
Method method=action.getClass().getMethod(methodName, null);
//获取request对象
HttpServletRequest request=ServletActionContext.getRequest();
//检查注解
boolean flag=isCheckLimit(request,method);
if(!flag){
//没有权限,通过struts2转到事先定义好的页面
return "popmsg_popedom";
}
//有权限,可以调用action中的方法
String returnvalue=invocation.invoke();
return returnvalue;
}
public boolean isCheckLimit(HttpServletRequest request, Method method) {
if(method==null){
return false;
}
//获取当前的登陆用户
SysUser sysUser=SessionUtils.getSysUserFormSession(request);
if(sysUser==null){
return false;
}
//如果用户的权限组为空
if(sysUser.getSysRole()==null){
return false;
}
//获取当前登陆用户的权限组id
String roleId=sysUser.getSysRole().getId();
//处理注解
/*
* @Limit(module="group",privilege="list")
public String list(){
....
}
*/
//判断用户请求的method上面是否存在注解
boolean isAnnotationPresent= method.isAnnotationPresent(Limit.class);
//不存在注解
if(!isAnnotationPresent){
return false;
}
//存在注解,拿到由Limit类写的注解
Limit limit=method.getAnnotation(Limit.class);
//获取注解上的值
String module=limit.module(); //模块名称
String privilege=limit.privilege(); //操作名称
/**
* 如果登陆用户的权限组id+注解上的@Limit(module="group",privilege="list")
* * 在sys_popedom_privilege表中存在 flag=true;
* * 在sys_popedom_privilege表中不存在 flag=false;
*/
boolean flag=false;
//通过自己封装的方法拿到操作权限的业务层对象
ISysPopedomPrivilegeService sysPopedomPrivilegeService=
(ISysPopedomPrivilegeService)ServiceProvinder.getService(ISysPopedomPrivilegeService.SERVICE_NAME);
//查询sys_popedom_privilege表中的所有的数据
//因为后面用到二级缓存,因此这里直接查询出所有的操作权限,而不是通过登陆用户的权限组来查询
List list=sysPopedomPrivilegeService.findAllSysPopedomPrivileges();
if(list!=null&&list.size()>0){
for(int i=0;i
isLogin,logout,top,left
/WEB-INF/page/popmsg_popedom.jsp
import cn.grace.annotation.Limit;
public class testUserAction {
/** 用户添加页面 */
@Limit(module="user",privilege="add")
public String add(){
return "add";
}
/** 用户添加 **/
@Limit(module="user",privilege="save")
public String save(){
return "save";
}
/** 用户删除 **/
@Limit(module="user",privilege="delete")
public String delete(){
return "delete";
}
/** 用户修改页面 **/
@Limit(module="user",privilege="edit")
public String edit() {
return "edit";
}
/** 用户修改 **/
@Limit(module="user",privilege="update")
public String update() {
return "update";
}
/** 用户列表 (查询) */
@Limit(module="user",privilege="list")
public String list() {
return "list";
}
}
至此,权限控制实现完毕。
1.系统管理的权限id(roleId)为:8af0897545e4c91b0145e4cd385d0002;而在sys_popedom_privilege表中,roleId为:8af0897545e4c91b0145e4cd385d0002,拥有所有模块和操作,则系统管理员拥有所有模块的所有操作权限。
2.部门经理的权限id(roleId)为:8af09d7845fe6ef90145fe70a0a80001;而在sys_popedom_privilege表中,roleId为:8af09d7845fe6ef90145fe70a0a80001,拥有部门模块的所有操作(9个),则部门经理拥有部门模块的所有9个操作权限,但没有其他(例如city和code模块)模块的操作权限。
3.小明的权限id(roleId)为:8af0897545e4c91b0145e4cd65b30003;而在sys_popedom_privilege表中,roleId为:8af0897545e4c91b0145e4cd65b30003,仅拥有部门模块的部分操作(比部门经理比少了list和edit操作),则小明拥有部门模块下的部分操作权限。如下图,其中roleId为8af0897545e4c91b0145e4cd65b30003对应的模块和操作只有下图前7行。