JiveJdon的CRUD流程实现3

上篇 

数据访问权限实现

修改帖子对于主题贴或回帖目前没有区别,但是,修改帖子有一个业务约束前提:帖子如果有回帖,帖子发布者就不能进行修改(管理员除外)。
这个约束需要实现两点:
当不符合编辑条件时,用户调用messageAction.shtml进入编辑页面时,应该推出不符合编辑条件禁止更新的页面。
当用户符合条件进入后,向messageSaveAction.shtml提交修改后的帖子内容时,我们也必须再次检验是否符合条件编辑,这样避免安全漏洞。
先谈第二个约束的实现,这个可以放在ForumMessageShell中实现,和以上业务核心分离,这样便于修改拓展。其实,从前面用户访问权限章节可以得知,在ForumMessageShell已经加入了权限的验证,只有是本贴作者或Admin角色才能修改帖子;这个功能已经实现,还有另外一个权限约束功能:如果该贴已经有回帖,就是创建者本人也无法修改,这个权限判断不但涉及登陆安全系统;又涉及业务数据系统,有一定难度,关键问题是:如何判断一个帖子是否有回帖,也就是是否子贴Childern,这个涉及后面章节将要解决的树形结构问题。
再来谈谈第一个约束实现:
第一个约束实现有一定技巧,因为在Jdon框架册CRUD下设计,与messageAction.shtml对应的ModelViewAction是在Jdon框架中,除非我们继承ModelViewAction自己再做一个子类,然后在这个子类中进行是否符合编辑条件判断,这个方式将权限约束洒在Service层以外,难以维护,我们还是需要在业务Service层实现权限约束。
我们知道Jdon框架ModelViewAction的原理主要是通过jdonframework.xml和服务层的方法发生调用的:
<model key="messageId"
class="com.jdon.jivejdon.model.ForumMessage">
<actionForm name="messageForm"/>
<handler>
<service ref="forumMessageService">
<!—ModelViewAction调用这个方法获取ForumMessage   -->
<getMethod name="getMessageForUpdate"/>
<createMethod name="createTopicMessage"/>
<updateMethod name="updateMessage"/>
<deleteMethod name="deleteMessage"/>
</service>
</handler>
</model>
ModelViewAction通过ForumMessageService的getMessage方法获得一个已经存在的ForumMessage对象,然后推到Jsp页面中,这样,浏览器前的用户可以在原来的内容上进行修改。
如果我们在ForumMessageService的getMessageForUpdate方法中进行权限验证一下,如果当前操作不符合编辑条件时,我们就通过getMessage方法返回一个空值,详细代码如下:
public ForumMessage getMessageForUpdate(Long messageId) {
ForumMessage forumMessage = super.getMessage(messageId);
if (forumMessage == null)
return null;
//是否是该贴的创建者
if (!updateMessageAuthCheck1(forumMessage)) {
return null;
}
//该贴是否有跟帖
if (!updateMessageAuthCheck2(forumMessage)) {
return null;
}
return forumMessage;
}
这样ModelViewAction得到一个空值,会推出一个错误页面,这会通过” id.notfound”标识将application.properties中信息定义显示出来,我们可以定义这个id.notfound值:
id.notfound = sorry, not found the data, maybe no permission to operate it
当然,如果你觉得这样做显示信息比较粗糙,可以通过继承ModelViewAction推出更详细的出错信息显示。

删除帖子

帖子删除除了实体内容的删除外,主要是帖子关系的删除,这种关系是和ForumThread和Forum相关,也需要区分是否是主题贴。
如果是主题贴,不但删除该贴实体,还要删除ForumThread,然后再删除该主题贴所有的跟帖。
如果是回帖,则只要删除该贴实体,然后删除该贴的所有回帖。
关于是否删除该贴的所有回帖,需要提供删除者一个可选功能,当然,删除的权限只能由管理员Admin实现。对于管理者,需要提供一个界面功能选择:是否删除其所有子贴?这个我们又要修改ForumMessage模型了,增加includeChildern字段。
这里有两种情况:
只删除一个贴,如果这个贴有回帖,那么就不能删除,建议其选择第2中情况:删除所有根贴。
删除本帖及其所有跟帖。
对于第一种情况,我们在ForumMessageShell的deleteMessage方法中增加如下代码
public void deleteMessage(EventModel em) {
ForumMessage forumMessage = (ForumMessage)em.getModel();
boolean deleteChildern = forumMessage.isIncludeChildern();
……..
if ((!deleteChildern) && (hasChildern(forumMessage))){
em.setErrors(Constants.NOPERMISSIONS2);  
return;
}          
super.deleteMessage(em);
}
如果前台选择不删除子贴,但是该贴又有子贴,返回错误,让管理员或发布者必须选择删除子贴。实际上,发布者自己只能删除那些没有回帖的帖子。
对于第二种情况,我们在ForumMessageService再增加一种删除方法:
void deleteRecursiveMessage(EventModel em)
这是将本帖及其子贴全部删除。
该方法的权限只有Admin可以访问,设置方法访问权限,在jivejdon_permission.xml中设置方法配置:
<method name="deleteRecursiveMessage">
<role>Admin</role>
</method>                  
删除帖子的界面设计:
在界面设计时,根据选择不同提供不同的删除方法调用,在deleteMessage.jsp中:
<input type="checkbox" name="deleteRecursiveMessage" value="checkbox">删除子贴
<html:hidden property="method" value="delete"/>
<script type="text/JavaScript">
function delConfirm(theForm){
if (confirm( '删除你自己发表的贴子吗? ! \n\n 你肯定吗?  '))
{
if (theForm.deleteRecursiveMessage.checked){
theForm.method.value="deleteRecursiveMessage";
}
theForm.submit();
return true;
}else{
return false;
}
}
</script>
当用户选择checkbox删除子贴时,那么该表单提交时,method(或者action)的只就被改变,根据Jdon框架的服务调用命令模式,虽然deleteRecursiveMessage不在jdonframework.xml的定义中,但是将直接调用ForumMessageService的deleteRecursiveMessage方法。
业务设计:
删除所有回帖之前必须查询获得该贴的所有跟帖,也就是查询parentMessageID为该贴ID的所有帖子。在解决“删除主题贴将会删除其所有回帖”之前,首先我们需要获得一个主题下的所有回帖,这涉及到树形结构的解决。
帖子的删除其他权限设计等同与帖子修改权限。

下篇