oa_11

初步实现授权管理的界面,重点在于:
1、理解DWR如何使用,理解DWR如何与spring集成
2、理解权限表格的初始化操作(initTable的原理)


[quote]作为一个java open source library,DWR可以帮助开发人员完成应用AJAX技术的web程序。它可以让浏览器上的javascript方法调用运行在web服务器上java方法。

DWR主要由两部门组成。javascript与web服务器通信并更新web页;运行在web服务器的Servlet处理请求并把响应发回浏览器。

DWR采用新颖的方法实现了AJAX(本来也没有确切的定义),在java代码基础上动态的生成javascript代码。web开发者可以直接调用这些javascript代码,然而真正的代码是运行在web服务器上的java code。出与安全考虑,开发者必须配置哪些java class暴露给DWR.(dwr.xml)

这种从(java到javascript)调用机制给用户一种感觉,好象常规的RPC机制,或RMI or SOAP.但是它运行在web上,不需要任何浏览器插件。

DWR不认为浏览器和web服务器之间协议重要,把系统界面放在首位。最大挑战是java method call的同步特征与ajax异步特性之间的矛盾。在异步模型里,结果只有在方法结束后才有效。DWR解决了这个问题,把回调函数当成参数传给方法,处理完成后,自动调用回调方法。

这个图表显示了,通过javascript事件,DWR能改变select的内容,当然这些内容由java代码返回。 javascript函数Data.getOptions(populateList)由DWR动态生成,这个函数会调用java class Data类的方法。DWR处理如何远程调用,包括转换所有的参数和返回的结果(javascript\java)。java方法执行完后,执行回调方法populateList。在整个过程中我们就想在用本地的方法一样。[/quote]
dwr.xml

[quote]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="spring" javascript="aclManager">
<param name="beanName" value="aclManager"/>
</create>
</allow>
</dwr>[/quote]

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<!-- Standard Action Servlet Configuration (with debugging) -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>


<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
<filter-name>Spring character encoding filter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Spring character encoding filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
<filter-name>pagerFilter</filter-name>
<filter-class>com.bjsxt.oa.web.PagerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>pagerFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>


</web-app>



index.jsp


<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@include file="/common/common.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<link href="style/oa.css" rel="stylesheet" type="text/css">
<script language="javascript" src="script/public.js"></script>
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<script type="text/javascript" src="dwr/interface/aclManager.js"></script>
<script type="text/javascript">
function addOrUpdatePermission(field){
aclManager.addOrUpdatePermission(
"${aclForm.principalType}",
${aclForm.principalId},
field.moduleId,
field.permission,
field.checked
);
}

function initTable(){
aclManager.searchAclRecord(
"${aclForm.principalType}",
${aclForm.principalId},
function(data){
for(var i=0; i<data.length; i++){
var moduleId = data[i][0];
var cState = data[i][1];
var rState = data[i][2];
var uState = data[i][3];
var dState = data[i][4];
$(moduleId+"_C").checked = cState == 0 ? false : true;
$(moduleId+"_R").checked = rState == 0 ? false : true;
$(moduleId+"_U").checked = uState == 0 ? false : true;
$(moduleId+"_D").checked = dState == 0 ? false : true;
}
}
);
}


</script>
<c:choose>
<c:when test="${aclForm.principalType eq 'User'}">
<c:set var="title" value="请给用户【${user.person.name}】授权"></c:set>
</c:when>
<c:otherwise>
<c:set var="title" value="请给角色【${role.name}】授权"></c:set>
</c:otherwise>
</c:choose>
<title>${title }</title>
</head>
<body onload="initTable()">
<center>
<TABLE class="tableEdit" border="0" cellspacing="1" cellpadding="0" style="width:580px;">
<TBODY>
<TR>
<!-- 这里是添加、编辑界面的标题 -->
<td align="center" class="tdEditTitle">${title}</TD>
</TR>
<TR>
<td>
<!-- 主输入域开始 -->
<table class="tableEdit" style="width:580px;" cellspacing="0" border="0" cellpadding="0">
<tr>
<td class="tdEditLabel" >顶级模块</td>
<td class="tdEditLabel" >二级模块</td>
<td class="tdEditLabel" >权限</td>
<c:if test="${aclForm.principalType eq 'User'}">
<td class="tdEditLabel" >不继承</td>
</c:if>
<td class="tdEditLabel" >启用</td>
</tr>
<c:forEach items="${modules}" var="module">
<tr>
<td>${module.name}</td>
<td></td>
<td>
<input type="checkbox" id="${module.id }_C" moduleId="${module.id }" permission="0" onclick="addOrUpdatePermission(this)">C
<input type="checkbox" id="${module.id }_R" moduleId="${module.id }" permission="1" onclick="addOrUpdatePermission(this)">R
<input type="checkbox" id="${module.id }_U" moduleId="${module.id }" permission="2" onclick="addOrUpdatePermission(this)">U
<input type="checkbox" id="${module.id }_D" moduleId="${module.id }" permission="3" onclick="addOrUpdatePermission(this)">D
</td>
<c:if test="${aclForm.principalType eq 'User'}">
<td>
<input type="checkbox">
</td>
</c:if>
<td>
<input type="checkbox">
</td>
</tr>
<c:forEach items="${module.children}" var="child">
<tr>
<td></td>
<td>${child.name}</td>
<td>
<input type="checkbox" id="${child.id }_C" moduleId="${child.id }" permission="0" onclick="addOrUpdatePermission(this)">C
<input type="checkbox" id="${child.id }_R" moduleId="${child.id }" permission="1" onclick="addOrUpdatePermission(this)">R
<input type="checkbox" id="${child.id }_U" moduleId="${child.id }" permission="2" onclick="addOrUpdatePermission(this)">U
<input type="checkbox" id="${child.id }_D" moduleId="${child.id }" permission="3" onclick="addOrUpdatePermission(this)">D
</td>
<c:if test="${aclForm.principalType eq 'User'}">
<td>
<input type="checkbox">
</td>
</c:if>
<td>
<input type="checkbox">
</td>
</tr>
</c:forEach>
</c:forEach>
</table>

<!-- 主输入域结束 -->
</td>
</TR>
</TBODY>
</TABLE>

<TABLE>
<TR align="center">
<TD colspan="3" bgcolor="#EFF3F7">
<input type="button" class="MyButton"
value="关闭窗口" onclick="window.close()">
</TD>
</TR>
</TABLE>
</center>
</body>
</html>



package com.bjsxt.oa.manager.impl;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.bjsxt.oa.manager.AclManager;
import com.bjsxt.oa.manager.Permission;
import com.bjsxt.oa.model.ACL;

public class AclManagerImpl extends AbstractManager implements AclManager {

public void addOrUpdatePermission(String principalType, int principalId,
int moduleId, int permission, boolean yes) {

//查找ACL对象
ACL acl = findACL(principalType, principalId, moduleId);

if(acl != null){
//根据permission和yes,更新aclState的值
acl.setPermission(permission, yes);
getHibernateTemplate().update(acl);
return;
}

acl = new ACL();
acl.setPrincipalType(principalType);
acl.setPrincipalId(principalId);
acl.setModuleId(moduleId);
//根据permission和yes,更新aclState的值
acl.setPermission(permission, yes);
getHibernateTemplate().save(acl);
}

public void addOrUpdateUserExtends(int userId, int moduleId, boolean yes) {
ACL acl = findACL(ACL.TYPE_USER, userId, moduleId);
if(acl != null){
acl.setExtends(yes);
getHibernateTemplate().update(acl);
return;
}
acl = new ACL();
acl.setPrincipalType(ACL.TYPE_USER);
acl.setPrincipalId(userId);
acl.setModuleId(moduleId);
acl.setExtends(yes);
getHibernateTemplate().save(acl);
}

public void delPermission(String principalType, int principalId,
int moduleId) {
ACL acl = findACL(principalType, principalId, moduleId);
if(acl != null){
getHibernateTemplate().delete(acl);
}
}

public boolean hasPermission(int userId, int moduleId, int permission) {

//根据用户标识和模块标识查找授权记录
ACL acl = findACL(ACL.TYPE_USER,userId,moduleId);

//有授权记录
if(acl != null){
int yesOrNo = acl.getPermission(permission);

//如果是确定的授权
if(yesOrNo != ACL.ACL_NEUTRAL){
return yesOrNo == ACL.ACL_YES ? true : false;
}
}

//继续查找用户的角色的授权记录

String hql = "select r.id from UsersRoles ur join ur.role r join ur.user u " +
"where u.id = ? order by ur.orderNo";
List roleIds = getHibernateTemplate().find(hql, userId);
for (Iterator iterator = roleIds.iterator(); iterator.hasNext();) {
Integer rid = (Integer) iterator.next();
acl = findACL(ACL.TYPE_ROLE, rid, moduleId);
if(acl != null){
return acl.getPermission(permission) == ACL.ACL_YES ? true : false;
}
}

return false;
}

public List searchModules(int userId) {

//查询用户拥有的角色,并按优先级从低到高排序
String hql = "select r.id from UsersRoles ur join ur.role r join ur.user u " +
"where u.id = ? order by ur.orderNo desc";
List roleIds = getHibernateTemplate().find(hql, userId);

Map temp = new HashMap();

//依次查找角色的授权列表
for (Iterator iterator = roleIds.iterator(); iterator.hasNext();) {
Integer rid = (Integer) iterator.next();
List acls = findRoleAcls(rid);
for (Iterator iterator2 = acls.iterator(); iterator2.hasNext();) {
ACL acl = (ACL) iterator2.next();
temp.put(acl.getModuleId(), acl);
}
}

//针对用户查找有效的用户授权列表
List acls = findUserAcls(userId);
for (Iterator iterator = acls.iterator(); iterator.hasNext();) {
ACL acl = (ACL) iterator.next();
temp.put(acl.getModuleId(), acl);
}

//去除掉那些没有读取权限的授权记录
Set entries = temp.entrySet();
for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
ACL acl = (ACL)entry.getValue();
if(acl.getPermission(Permission.READ) != ACL.ACL_YES){
iterator.remove();
}
}

if(temp.isEmpty()){
return null;
}

String searchModules = "select m from Module m where m.id in (:ids) order by m.orderNo";
return getSession().createQuery(searchModules)
.setParameterList("ids", temp.keySet())
.list();
}

public List searchAclRecord(String principalType, int principalId) {
String sql = "select moduleId,aclState&1,aclState&2,aclState&4,aclState&8 from t_acl " +
"where principalType = '"+principalType+"' " +
"and principalId = "+principalId;

return getSession().createSQLQuery(sql).list();
}

private ACL findACL(String principalType,int principalId,int moduleId){
String hql = "select a from ACL a where a.principalType = ? and a.principalId = ? and a.moduleId = ?";
ACL acl = (ACL)getSession().createQuery(hql)
.setParameter(0, principalType)
.setParameter(1, principalId)
.setParameter(2, moduleId)
.uniqueResult();
return acl;
}

private List findRoleAcls(int roleId){
return getHibernateTemplate().find(
"select acl from ACL acl where acl.principalType = ? " +
"and acl.principalId=?",
new Object[]{ACL.TYPE_ROLE,roleId}
);
}

private List findUserAcls(int userId){
return getHibernateTemplate().find(
"select acl from ACL acl where acl.principalType = ? " +
"and acl.principalId=? and acl.aclTriState = ?",
new Object[]{ACL.TYPE_USER,userId,ACL.ACL_TRI_STATE_UNEXTENDS}
);
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值