功能权限管理
父功能点显示改成树
class="easyui-combotree"
[
{id:'1',text:'基础档案',children:[
{id:'',text:'',children:[{}]}
]
}
]
重写FunctionDaoImpl的findAll方法
@Repository
public class FunctionDaoImpl extends BaseDaoImpl<Function> implements IFunctionDao {
public List<Function> findAll() {
String hql = "FROM Function f WHERE f.parentFunction IS NULL";
List<Function> list = (List<Function>) this.getHibernateTemplate().find(hql);
return list;
}
}
修改配置文件,改成立即加载
在Function的实体类中添加
public String getText(){
return name;
}
并且在FunctionAction的方法中修改排除项
public String listajax(){
List<Function> list=functionService.findAll();
//this.java2Json(list, new String[]{"parentFunction","roles","children"});
this.java2Json(list, new String[]{"parentFunction","roles"});
return NONE;
}
效果如图:
角色管理
添加角色功能
将页面的编号改成关键字(记得将Role.hbm.xml的assigned改成uuid)
第一步:修改页面,使用ztree勾选效果(checkbox)
第二步:修改ajax方法的请求URL地址
第三步:为保存按钮绑定事件,提交表单
获取ztree提交的数据
//根据ztree的id获取ztree对象
var treeObj=$.fn.zTree.getZTreeObj("functionTree");
//获取ztree上选中的节点,返回数组对象
var nodes=treeObj.getCheckedNodes(true);
服务端实现
创建对应的action service dao
@Controller
@Scope("prototype")
public class RoleAction extends BaseAction<Role> {
@Autowired
private IRoleService roleService;
private String functionIds;
public void setFunctionIds(String functionIds) {
this.functionIds = functionIds;
}
/**
* 添加角色
*/
public String add(){
roleService.save(model,functionIds);
return LIST;
}
}
@Service
@Transactional
public class RoleServiceImpl implements IRoleService {
@Autowired
private IRoleDao roleDao;
/**
* 保存一个角色,同时关联权限
*/
public void save(Role role, String functionIds) {
roleDao.save(role);
if(StringUtils.isNotBlank(functionIds)){
String[] fids=functionIds.split(",");
for (String functionId : fids) {
//方法一:根据functionId来查询权限对象
//方法二:手动构造一个对象,设置id,对象状态为托管状态
Function function=new Function(functionId);
//角色关联权限
role.getFunctions().add(function);
}
}
}
}
@Repository
public class RoleDaoImpl extends BaseDaoImpl<Role> implements IRoleDao {
}
在function的实体类中提供空参数的构造方法,提供有参数的构造方法
public Function() {}
public Function(String functionId) {
this.id=functionId;
}
注意:
属性驱动
当仅从页面接收数据,可以省略get方法
但是当页面需要回显数据的时候,get方法不能省略
角色分页查询
修改role.jsp页面中datagrid的URL地址
/**
* 分页查询
*/
public String pageQuery(){
roleService.pageQuery(pageBean);
this.java2Json(pageBean, new String[]{"functions","users"});
return NONE;
}
用户管理
添加用户(添加用户的时候,要赋予角色)
角色可以去角色管理添加
页面调整
第一步:发送ajax请求,获取角色数据,在回调函数中动态展示角色数据,展示为checkbox
第二步:在RoleAction中提供listajax方法,查询所有角色,返回json数据
/**
* 查询所有的角色数据
*/
public String listajax(){
List<Role> list=roleService.findAll();
this.java2Json(list, new String[]{"functions","users"});
return NONE;
}
第三步:为保存按钮绑定事件,提交表单
服务端实现
在UserAction中提供add方法,保存一个用户
分页查询
效果如图:
第一步:修改userlist.jsp页面中datagrid的URL地址
在数据表格中,修改field,由电话修改为角色
第二步:在UserAction中提供分页查询方法(将User实体类中不需要的排除了)
第三步:在User类中提供getRoleNames方法
解决页面显示时间有问题
修改Realm中授权方法(查询数据库)
如何通过以后id关联的对应的权限过程
分析:
用户和权限是没有关系的 中间通过角色表来关联的
用户和角色是多对多 角色和权限是多对多
方法一:比较笨的方法
根据用户id查出用户,---查出角色---查出权限
通过
用户表t_user---用户角色表user_role---角色表auth_role--角色权限表role_function--权限表auth_function
在FunctionDao中扩展方法,根据用户id查询对应的权限
select * from auth_function f left out join role_function rf on f.id=rf.function_id
left out join ....一直连接下去就可以了。比较费劲,因此写hql,中间没有中间表,写起来稍微好点
不查询所有的,只查询权限表的字段
重复数据
一个用户对应多个角色,多个角色对应的权限有交叉,就会出现重复数据
比如:一个用户对应两个角色,两个角色对应的权限有交叉,就会出现重复数据
通过admin账号登陆出现这个原因是配置文件设置了
可以正常显示了
使用ehcache缓存权限数据(只需要配置就可以了)
ehcache是专门缓存插件,可以缓存Java对象,提高系统性能。
第一步:在pom.xml文件中引入ehcache的依赖
第二步:在项目中提供ehcache的配置文件
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
第三步:在spring配置文件中配置缓存管理器对象,并注入给安全管理器对象
<!-- 注册安全管理器对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="bosRealm"/>
<!-- 注入缓存管理器 -->
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 注册缓存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 注入ehcache的配置文件 -->
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>
如何测试这个缓存有效
步骤:
通过这个来配置时间的(这个表示的是两分钟)
timeToIdleSeconds="120"
timeToLiveSeconds="120"
系统菜单根据登录人动态展示
第一步:修改index.jsp页面中ajax方法的请求地址
/**
* 根据当前登录人查询对应的菜单数据
*/
public String findMenu(){
List<Function> list=functionService.findMenu();
this.java2Json(list, new String[]{"parentFunction","roles","children"});
return NONE;
}
/**
* 根据当前登录人查询对应的菜单数据
*/
public List<Function> findMenu() {
User user = BOSUtils.getUser();
List<Function> list =null;
if(user.getUsername().equals("admin")){
//如果是超级管理员,查询所有菜单
list= functionDao.findAllMenu();
}else{
//其他用户,根据用户id查询菜单
list=functionDao.findMenuByUserId(user.getId());
}
return list;
}
// 查询所有菜单 1表示生成菜单 0表示不生成菜单
public List<Function> findAllMenu() {
String hql = "FROM Function f WHERE f.generatemenu = '1' ORDER BY f.zindex DESC";
List<Function> list = (List<Function>) this.getHibernateTemplate().find(hql);
return list;
}
//根据用户id查询菜单
public List<Function> findMenuByUserId(String userId) {
String hql = "SELECT DISTINCT f FROM Function f LEFT OUTER JOIN f.roles"
+ " r LEFT OUTER JOIN r.users u WHERE u.id = ? AND f.generatemenu = '1' "
+ "ORDER BY f.zindex DESC";
List<Function> list = (List<Function>) this.getHibernateTemplate().find(hql, userId);
return list;
}
效果
新加一个账号,只给部分权限
菜单只显示了部分