- 浏览: 34950 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
308655406:
讲了原理 讲了注意事项 居然没有举例讲怎么用。。。
jQuery 数据缓存data(name, value)详解及实现
4.3 权限验证模块设计
一个好的权限管理机制在项目中应用时,最好不要让程序员在具体业务代码的方法中来判断用户权限。因为这意味着大量重复的代码。同时,也会导致权限机制的修改造成所有业务代码都需要修改一遍。
最好办法是实现与具体业务代码无关的独立的权限验证模块。这个模块可以拦截用户对资源的访问请求,并且在该请求被实施前做出权限判断,将权限不符的访问导向警告或提示页面。
在普通的JSP项目中,我们往往会利用Tomcat的Servlet filter机制来实现这样的功能,但filter机制的颗粒度不够,无法做到ACTION级别。另一个问题是,在JSF项目中,页面的跳转默认使用的是Forward形式,而不是redirect形式的URL重定向,因此Filter往往无法截获页面的转向。
因此,在JSF项目中我们首先需要解决如何截获到用户对资源的访问的问题。
4.3.1 捕获URL级别的资源访问
在JSF中,我们有时候会使用PhaseListener观察JSF生命周期,这给我们一个思路,通过PhaseListener 可以在一个点上(JSF生命周期的Restore View phase阶段)来获取请求和输出路径信息(这个路径实际上就是我们定义的URL类型的资源)。路径获取后我们就可以据此进行鉴权,从而避免在每个页面或者每个backing bean中判断用户访问权限,造成过多的冗余代码和管理上的混乱。
步骤一:在faces-config.xml中注册 自定义的PhaseListener。
<lifecycle> <phase-listener>com.laomao.view.listener.PermissionPhaseListener</phase-listener> </lifecycle> |
步骤二:实现我们自己的PhaseListener接口
package com.laomao.view.listener; import javax.el.MethodExpression; import javax.faces.FacesException; import javax.faces.application.Application; import javax.faces.application.NavigationHandler; import javax.faces.context.FacesContext; import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
public class PermissionPhaseListener implements PhaseListener {
private static Log log = LogFactory.getLog(PermissionPhaseListener.class);
@Override public void afterPhase(PhaseEvent event) { PhaseId phaseId = event.getPhaseId(); if (phaseId == PhaseId.RESTORE_VIEW || phaseId == PhaseId.INVOKE_APPLICATION) { FacesContext currentContext = FacesContext.getCurrentInstance(); String viewId= currentContext.getViewRoot().getViewId(); //ViewId 就是我们需要的路径,类似URL,如/noPermission.xhtml System.out.println("afterPhase: " + viewId);
//判断用户的操作权限 boolean isEnabled = true; //TODO: 鉴权代码 //…
if(!isEnabled){ gotoNoPermissionPage(); } } }
/** * 转入无权限声明页面 * @param expression */ private void gotoNoPermissionPage() { FacesContext context = FacesContext.getCurrentInstance(); Application application = context.getApplication();
NavigationHandler navHandler = application.getNavigationHandler(); navHandler.handleNavigation(context, null, Constants.NAVIGATION_NO_PERMISSION); context.renderResponse(); } }
|
PhaseListener可以捕获到URL的变化,对于页面内部的操作则无能为力了。例如CommandButton的操作,可能删除了一条记录,但URL却没有变化,仅仅是页面局部进行了刷新。因此,我们还需要一个可以捕获到用户对ACTION类型的资源的访问的利器。这个利器就是ActionListener。
4.3.2 捕获ACTION级别的资源访问
当一个按钮被按下,或者命令联结被点击时,JSF会在invork application阶段的broadcast
event时通过ActionListener调用事先绑定的事件处理方法。如果有用户自定义的ActionListener时,JSF将使用用户自定义ActionListener来代替默认的ActionListener。
用户自定义ActionListener必须实现javax.faces.event.ActionListener接口,并实现其接口方法:public void processAction(ActionEvent actionEvent)。
注意,在这个实现方法里,必须调用控件的事件处理方法(JSF Backing Bean中的事件处理方法),并对其返回值做出画面迁移处理和其他你自己的处理等。
步骤一:在faces-config.xml中注册 自定义的ActionListener。
<application> <action-listener>com.laomao.view.listener.ActionListenerImpl</action-listener> </application> |
步骤二:实现我们自己的ActionListener接口
package com.laomao.view.listener; import javax.el.ELContext; import javax.el.MethodExpression; import javax.faces.FacesException; import javax.faces.application.Application; import javax.faces.application.NavigationHandler; import javax.faces.component.ActionSource2; import javax.faces.context.FacesContext; import javax.faces.el.EvaluationException; import javax.faces.el.MethodBinding; import javax.faces.event.AbortProcessingException; import javax.faces.event.ActionEvent; import javax.faces.event.ActionListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
public class ActionListenerImpl implements ActionListener { private static Log log = LogFactory.getLog(PermissionPhaseListener.class);
@Override public void processAction(ActionEvent actionEvent) throws AbortProcessingException { FacesContext facesContext = FacesContext.getCurrentInstance(); Application application = facesContext.getApplication();
ActionSource2 actionSource = (ActionSource2)actionEvent.getComponent();
MethodBinding methodBinding = actionSource.getAction();
String fromAction; String outcome; if (methodBinding == null) { fromAction = null; outcome = null; } else { fromAction = methodBinding.getExpressionString();
try { outcome = (String) methodBinding.invoke(facesContext, null); //fromAction与faces-config.xml中登记的是一致的 //fromAction: #{loginController.loginAction}, outcome: success System.out.println("fromAction: " + fromAction + ", outcome: " + outcome);
boolean isEnabled = true; //TODO: 鉴权代码 //… if(!isEnabled){ //如果无此权限,转到权限不足页面 gotoNoPermissionPage(actionSource.getActionExpression()); }
} catch (EvaluationException e) { Throwable cause = e.getCause(); if (cause != null && cause instanceof AbortProcessingException) { throw (AbortProcessingException)cause; } else { throw new FacesException("Error calling action method of component with id " + actionEvent.getComponent().getClientId(facesContext), e); } } catch (RuntimeException e) { throw new FacesException("Error calling action method of component with id " + actionEvent.getComponent().getClientId(facesContext), e); } }
NavigationHandler navigationHandler = application.getNavigationHandler(); navigationHandler.handleNavigation(facesContext,fromAction,outcome); //Render Response if needed facesContext.renderResponse();
}
/** * 转入无权限声明页面 * @param expression */ private void gotoNoPermissionPage(MethodExpression expression) { FacesContext context = FacesContext.getCurrentInstance(); Application application = context.getApplication();
NavigationHandler navHandler = application.getNavigationHandler(); navHandler.handleNavigation(context, null == expression ? null : expression.getExpressionString(), Constants.NAVIGATION_NO_PERMISSION); context.renderResponse(); }
} |
转:http://laomaowww.blog.163.com/blog/static/16600567320124751827427/
发表评论
-
JSF2 FORM组件
2013-01-14 18:10 770添加Form组件 标签h:form展示一个输入表单,包 ... -
JSF2 页面标签使用说明(一)
2013-01-14 18:08 1098Web页面代表了web应用 ... -
JSF2 使用bean验证
2013-01-14 18:03 799验证用户的输入来维 ... -
JSF相关表单控件收集
2013-01-14 17:52 711import javax.enterprise.contex ... -
jsf web.xml配置
2013-01-14 17:43 735<?xml version="1.0" ... -
JSF的ViewExpiredException异常处理 转
2012-12-24 14:08 920视图没有存储的异常 javax.faces.applicat ... -
JSF笔记 – JSF运行流程和生命周期介绍
2012-12-20 14:13 760JSF是一个Web应用,也会 ... -
JSF项目中实现基于RBAC模型的权限管理设计(一)(转)
2012-12-20 10:32 10651 概述 几乎所有的项目都会涉及到权限控制 ... -
JSF中session过期后视图恢复的问题
2012-12-20 10:16 1149在jsf中,一旦session过期,生命周期为session的 ... -
JSF获取页面路径和参数
2012-12-18 20:39 1130FacesContext facesContext ... -
JSF2拦截器
2012-12-18 20:40 1435/* * To change this template, c ...
相关推荐
主要讲述JSF的工作方式 JSF的工作方式 JSF架构 JSF模型 JSF事件类型
这是一个使用jsf框架实现简易登录功能的小例子,对于初学者可以参考一下。
JSF+hibernate实现批量删除,CRUD
基于JSF框架技术与Matlab的机械故障监测与诊断系统的设计与实现 基于JSF框架技术与Matlab的机械故障监测与诊断系统的设计与实现 基于JSF框架技术与Matlab的机械故障监测与诊断系统的设计与实现 基于JSF框架技术与...
本系统是基于jsf+spring+hibernate+ajax实现的一个网络文件管理系统.运行环境 WEB服务:TOMCAT6 数据库:SQLSERVER2005 JDK1.4以上 本系统采用了基于角色的权限管理
jsf(基于时间驱动模型) 介绍机遇时间驱动模型的材料
jsf实现基于ajax的上传例子
jsf1.2+ejb3.0实现的员工管理系统,做成了部分:一部分是ejb端,实现业务逻辑;另一部分是web端,实现web浏览。通过这个实例,你可以学会用jsf1.2和ejb3去做企业项目。内附源代码、分析和部署文档。
JSF添加项目实例JavaJSF的项目实例
本程序由JSF、Hibernate 、Spring整合编写,异步交互采用ajax4jsf。
IDEA创建JSF项目所需jar包.zip
JSF中文教程JSF中文教程JSF中文教程JSF中文教程
JSF初级项目开发实例,非常适合初学者了解项目开发的流程。
sun的jsf接口和实现的源文件下载,也可以在玻璃鱼项目中下载到!
jsf 中文文档jsf 中文文档jsf 中文文档jsf 中文文档
精通JSF基于EJB Hibernate Spring整合开发与项目
本系统为用jsf+ejb技术实现的一个简单的小型学生信息管理系统,其可以实现普通用户的注册与登录,登录成功后可以增加自己的学生信息。系统中还有内定的管理员用户admin,他可以实现对学生信息的增删查改。 部署可按...
文章里主要是把seam在jsf中的使用经验提一下,能让更多的人了解seam的实际应用和优势
资源名称:精通JSF—基于EJBHibernateSpring开发实践视频教程资源目录:【】chapter13_code【】Jsf第七章【】JSF第二章【】Jsf第五章【】Jsf第八章【】Jsf第六章【】Jsf第十三章【】Jsf第十五章【】Jsf第十六章【】...
jsf1.2+ejb3.0实现的员工管理系统 <br>1.项目说明: 本实例是一个用JSF1.2+EJB3.0实现的员工CRUD的一个实例,业务非常简单,主要是为了演示这两种技术的使用。若与商业应用类同,纯属巧合。 <br>2.源码...