权限系统,其实并不是你想象中的那样高大上,说白了就是些DAO层处理嘛。无非加上了一点额外的处理,仅此而已。 下面我来分享一下,我在一个小项目中关于权限系统开发的一点收获。
项目依赖
本例是基于是数据库开发的Java Web项目,所需jar包如下:
数据库相关
建库: create database PrivilegeSystem
用户表:
create table user(
id varchar(40) primary key,
username varchar(100) not null,
password varchar(100) not null
);
角色表:
create table role(
id varchar(40) primary key,
name varchar(100) not null,
description varchar(255)
);
权限表:
create table privilege(
id varchar(40) primary key,
name varchar(100) not null,
description varchar(255)
);
角色权限表:
> create table role_privilege(
> role_id varchar(40),
> privilege_id varchar(40),
> primary key(role_id,privilege_id),
> constraint role_id_FK foreign key(role_id) references role(id),
> constraint privilege_id_FK foreign key(privilege_id) references privilege(id)
> );
用户角色表:
create table user_role(
user_id varchar(40),
role_id varchar(40),
primary key(user_id,role_id),
constraint user_id_FK foreign key(user_id) references user(id),
# 这里使用了不一样的外键名称就是为了防止外键冲突
constraint role_id_FK1 foreign key(role_id) references role(id)
);
DAO层实现
由于这里面代码忒多,贴出来阅读效果也不好,待会文末我会留出完整的项目代码。贴一下项目目录吧,方便大家理解。
工具包
这里我就写一个操作数据库时常用的工具类吧,那就是UUID的工具类,这样可以保证我们数据库里面数据的唯一性,方便主键的处理。
package utils;
import java.util.UUID;
/**
* 创建出插入数据库的UUID工具类
*
* @author Administrator
*
*/
public class WebUtils {
public static String makeUUID() {
return UUID.randomUUID().toString();
}
}
过滤器
这里有两个过滤器都是比较常用的,一个是解决中文乱码的全局性质的过滤器。
防中文乱码
package web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class CharacterEncoding implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
权限处理
package web.filter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import domain.Privilege;
import domain.User;
import service.SecurityService;
/**
* 用于检测当前用户,拥有哪些权限,这是此项目的核心
*
* @author Administrator
*
*/
public class CheckPrivilegeFilter implements Filter {
/**
* 模拟数据库中存储的访问资源所对应的权限
*
* <br>
* 思路就是使用过滤器方式对要访问的资源进行过滤。拥有相关的权限的才可以正常的访问。
*/
public static Map<String, Privilege> map = new HashMap<String, Privilege>();
static {
Privilege add_p = new Privilege();
add_p.setName("add");
Privilege delete_p = new Privilege();
delete_p.setName("delete");
Privilege find_p = new Privilege();
find_p.setName("find");
map.put("URI_add", add_p);
map.put("URI_delete", delete_p);
map.put("URI_find", find_p);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 得到用户请求的URI资源定位
String uri = req.getRequestURI();
// 得到用户带有的自身的权限
Privilege p = map.get(uri);
// 处理权限问题。如果访问资源需要的权限为空,则放行,否则只有拥有相关权限的用户才能正常的访问该资源
if (p == null) {
chain.doFilter(request, response);
return;
}
// 需要权限的话,则检查用户是否登陆,未登录则提示用户先登录
User user = (User) req.getSession().getAttribute("user");
if (user == null) {
request.setAttribute("message", "请先登录!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
// 若用户已登录,则获取该用户拥有的所有的权限,然后
SecurityService service = new SecurityService();
List<Privilege> userPrivileges = service.getUserAllPrivilege(user.getId());
// 判断用户拥有的权限中是否包含资源访问需要的权限
if (!userPrivileges.contains(p)) {
request.setAttribute("message", "对不起,你的权限无法访问当前资源!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
// 拥有全部权限,正常的访问资源
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
总结
项目中有很多在开发中用得到的技术和经验,也比较适合新人练手。如果有兴趣,下面是完整的项目文件。