javax.faces是什么,如何使用FacesContext类
老铁们,大家好,相信还有很多朋友对于javax.faces是什么和如何使用FacesContext类的相关问题不太懂,没关系,今天就由我来为大家分享分享javax.faces是什么以及如何使用FacesContext类的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
uidata是什么
猪哥解答:
UI知道吧,UI界面这个名词如果不懂的话百度一下,Data你也应该知道是什么意思,连起来UIData可以理解为页面数据,页面的Table、Tree什么的可以用UIData来封装处理,下面给你转一个实例,也许会对你有帮助。
猪哥转帖:
UIData:表示数据集合,每个数据项由DataModel(标准JSF UIComponent Model Bean之一)的一个实例封装。该组件通常用来渲染表格、列表和树。
实例:
新建一个实体bean
package org.abc.jsf.vo;
public class ArticleVO{
private int id;
private String title;
private String body;
public ArticleVO(){
}
//getter setter
新建from类,jsf都是调用这类的方法
package org.abc.jsf.from;
import java.util.ArrayList;
import java.util.List;
import javax.faces.component.UIData;
import javax.faces.event.ActionEvent;
import jsftest.dal.ArticleDAL;
import jsftest.vo.ArticleVO;
import java.util.Collection;
public class ArticleForm{
private int id=0;
private String title;
private String body;
private ArrayList articles;
public ArticleForm(){
loadall();
}
private ArticleDAL dal=new ArticleDAL();
public void save()
{
ArticleVO vo=new ArticleVO();
vo.setBody(this.getBody());
vo.setTitle(this.getTitle());
if(this.getId()!=0)
{
vo.setId(this.getId());
}
dal.saveArticle(vo);
}
public void edit(ActionEvent event)
{//取页面集合的值
UIData table=(UIData) event.getComponent().getParent().getParent();
ArticleVO vo=new ArticleVO();//实例化ArticleVO
vo=(ArticleVO)table.getRowData();
this.setBody(vo.getBody());
this.setId(vo.getId());
this.setTitle(vo.getTitle());
}
public void delete(ActionEvent event)
{
UIData table=(UIData) event.getComponent().getParent().getParent();
ArticleVO vo=(ArticleVO)table.getRowData();
dal.deleteArticle(vo);
dal.LoadArticleAll();
}
public void loadall()
{
this.setArticles((ArrayList)dal.LoadArticleAll());
}
public String getBody(){
return body;
}
public int getId(){
return id;
}
public String getTitle(){
return title;
}
public Collection getArticles(){
//this.loadall();
if(articles==null)
{
articles=new ArrayList();
}
return articles;
}
public void setBody(String body){
this.body= body;
}
public void setId(int id){
this.id= id;
}
public void setTitle(String title){
this.title= title;
}
public void setArticles(ArrayList articles){
this.articles= articles;
}
}
前台页面:
<%@ page contentType="text/html; charset=GBK"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
<head>
<title>
jsp1
</title>
</head>
<body bgcolor="#ffffff">
<h:form>
<div align="left">
标题<h:inputText id="title" value="#{article.title}"/><br>
内容<h:inputTextarea id="currentMessage" value="#{article.body}" rows="10" cols="60"/>
<h:inputHidden value="#{article.id}"/>
</div>
<div align="center">
<h:commandButton value="save" action="#{article.save}"/>
</div>
<div align="center">
<h:commandButton value="clear" type="reset"/>
</div>
*************************************************************
<h:dataTable id="table" rowClasses="list-row" value="#{article.articles}" var="articles">
<h:column>
<h:outputText styleClass="small" value="#{articles.id}"/>
</h:column>
<h:column>
<h:commandLink id="editLink" actionListener="#{article.edit}">//绑定监听
<h:outputText value="edit"/>
</h:commandLink>
</h:column>
<h:column>
<h:commandLink id="deleteLink" actionListener="#{article.delete}">
<h:outputText value="delete"/>
</h:commandLink>
</h:column>
<h:column>
<h:outputText value="#{articles.title}"/>
</h:column>
<h:column>
<h:outputText value="#{articles.body}"/>
</h:column>
</h:dataTable>
</h:form>
</body>
</html>
如何使用FacesContext类
在Faces API中有两个类是要经常使用的.一个是FacesContext一个是ExternalContext,本篇文章讲解如何使用前者,在下面的一篇文章中在继续讲解任何使用后者:
对每个JSF请求,FacesServlet对象都会为其获取一个javax.faces. context.
FacesContext类的实例。FacesServlet对象将下列3个取自Web容器的对象传给javax.faces.context.FacesContextFactory对象的getFacesContext方法,以此来做到这一点:
● javax.servlet.ServletContext
● javax.servlet.ServletRequest
● javax.servlet.ServletResponse
这意味着FacesContext的实例里包含了所有处理JSF请求所需的每个请求的状态信息。图3-1展示了FacesContext实例里封装的其他一些对象。
如何使用FacesContext类
图3-1 FacesContext实例及其封装的对象
3.2.1获取当前实例
一个经常用到的方法是静态的getCurrentInstance方法,它返回当前的FacesContext实例。此方法的签名如下:
public static FacesContext getCurrentInstance()
下面的代码是一个用此方法获取FacesContext当前实例的例子:
FacesContext facesContext= FacesContext.getCurrentInstance();
3.2.2获取和修改组件树
FacesContext实例里最重要的内容是请求页面的组件树。组件树是由javax.faces.tree.Tree类来表示的(本章后面的“使用Tree类”一节会讨论)。FacesContext实例的tree属性就是Tree对象。
要获取或修改Tree对象,可使用tree属性的读取方法和赋值方法:
public abstract Tree getTree()
public abstract void setTree(Tree tree)
3.2.3添加和获取消息
在请求处理生命周期里,可能会遇到错误。比如,当验证器执行输入验证时,因为用户输入了不正确的值,验证可能失败;当组件试图把输入值转换为绑定到组件的模型对象所需的类型时,也可能会失败。所有消息都必须存放到FacesContext实例里以备后面进行处理。比如,您可能希望在页面里显示错误消息,从而为用户更正错误提供帮助。
错误消息是由javax.faces.application.Message接口(第11章再详细讨论)来表示的,您可以通过使用FacesContext类的addMessage方法向FacesContext实例里添加Message对象。这个方法的签名如下:
public abstract void addMessage(UIComponent component, Message message)
如果component不为空,新加入的message就关联到component上。否则,它就不与任何特定组件的实例相关。
举例来说,验证器在验证组件值失败时可调用FacesContext的addMessage方法,传入值无效的组件及一个包含特定错误消息的Message对象。
所有添加到FacesContext实例的Message对象都被加入到一个集合里。可通过调用getMessages方法的两个重载方法之一来获取加入的Message对象:
public abstract Iterator getMessages()
public abstract Iterator getMessages(UIComponent component)
第一种形式的调用在一个Iterator里返回所有Message对象,而第二种形式的调用则仅返回与给定UIComponent相关联的Message对象。
3.2.4添加和获取请求处理事件
UIComponent可以生成FacesEvent对象。比如,当单击一个UICommand组件时,它会生成一个ActionEvent对象(ActionEvent类是FacesEvent类的子类)。这个FacesEvent对象需要在FacesContext实例里保存起来,以备请求处理生命周期里的下一步处理事件时所用。
可通过使用FacesContext类的addFacesEvent方法向FacesContext实例添加FacesEvent对象。此方法的签名如下:
public abstract void addFacesEvent(FacesEvent event)
要提取先前添加的FacesEvent对象,可调用getFacesEvents方法,其签名如下:
public abstract Iterator getFacesEvents()
此方法返回FacesEvent时的顺序与其在队列中的顺序一致。
3.2.5向Response对象里写入信息
为了向Response对象里写入信息,FacesContext类提供了两个属性,一个是javax.faces.Context.ResponseStream类型,另一个是javax.faces.context.ResponseWriter类型。ResponseStream类型的对象用于输出二进制数据,而ResponseWriter类型的对象则用于输出字符。这些属性的读取方法和赋值方法如下:
public abstract ResponseStream getResponseStream()
public abstract void setResponseStream(ResponseStream responseStream)
public abstract ResponseWriter getResponseWriter()
public abstract void setResponseWriter(ResponseWriter responseWriter)
3.2.6获取和设置地区
第11章将会讨论到,JSF支持国际化和本地化。这意味着您可以根据用户的地区决定发送什么样的回应信息。locale属性里存放了当前处理中所用的Locale对象。
初始状况下,locale属性的值和网络浏览器里指定的地区是一样的,但可以修改这个值,从而发送输出所使用的地区将独立于浏览器所使用的地区。此属性的读取方法和赋值方法如下:
public abstract Locale getLocale()
public abstract void setLocale(Locale locale)
3.2.7操作请求处理生命周期
FacesContext类还提供了两个方法与请求处理生命周期进行交互:
●在当前阶段的处理完成后,调用renderResponse方法通知JSF实现把控制权转到呈现响应阶段。也就是说,处于当前阶段和呈现响应阶段之间的所有其他阶段都不再执行。
●调用responseComplete方法,告诉JSF实现此次请求的HTTP响应已经完成(比如在使用了HTTP重定向的情况下)。因此,当前阶段完成后,必须中止请求处理生命周期的处理。
这些方法的签名如下:
public abstract void renderResponse()
public abstract void responseComplete()
3.2.8获取其他请求状态信息
其他每个请求的状态信息封装在ExternalContext对象里,可以使用getExternalContext方法获取该对象:
public abstract ExternalContext getExternalContext()
受管理的bean和托管bean有什么区别
JSF引入了两个新概念:
managed bean和backing bean。JSF提供了强大的管理bean的机制。一个被JSF管理的JavaBean对象叫做managed bean。一个managed bean描述了一个bean如何创建和管理的,这些和bean的功能无关。
Backing bean定义了页面上的UI组件的属性和处理逻辑。每一个backing bean的属性对应一个组件或者组件的值。Backing bean同时定义了一组执行组件功能的方法,比如验证组件的数据,处理组件触发的事件,当组件activate时处理与导航相关的操作。
一个典型的JSF应用中的每一页面都有一个backing bean。然而,实际中强制页面和backing bean的一对一关系不是一个好的做法。它会导致类似代码重复的问题。实际情况中,一些页面也许会共享同一个backing bean。例如在JCatalog中,CreateProduct和EditProduct页面共享同一个ProductBean定义。
一个View对象是一个只在表示层使用的model对象。它包含着必须在View层显示的数据,包含着验证用户输入,处理事件,同业务逻辑层交互的逻辑。在基于JSF的应用中,backing bean就是view对象。在本文中,backing bean和view对象是可互换的概念。
与Struts中的ActionForm和Action概念相比,使用JSF中的backing bean开发更加符合OO设计习惯。一个backing bean不仅仅包含显示数据,还包括与这些数据相关的行为。而在Struts中,ActionForm和Action分别包含数据和逻辑。
我们大家都听说过domain object model(域对象模型)。那么domain object model和view object有什么不同呢?在一个简单的Web应用中,一个域对象模型经常穿越所有的层使用。然而在稍复杂的Web应用中,一个独立的view object是很需要的。Domain object model是关于业务对象(BO)的,应该属于业务逻辑层。它包含业务数据和与特定业务对象关联的业务逻辑。一个view object包含着显示相关的数据和行为。JCatalog的ProductListBean就是view object的一个好例子。它包含着表示层的数据和逻辑,比如分页相关的数据和逻辑。将view object和domain object model分开的一个缺点就是必须在两个对象模型之间进行data mapping。在JCatalog中,ProductBeanBuidler和UserBeanBuilder使用了基于反射的Commons-BeanUtils包来实现data mapping
具体地址讲述:http://infocenter.apusic.com/help/index.jsp?topic=/com.apusic.studio.doc.studio/output/eclipse/studio_web_managebean.html(managed bean)
http://infocenter.apusic.com/help/index.jsp?topic=/com.apusic.studio.doc.server/output/eclipse/backbean.html(backing bean)
区别:
您查询的关键词是:managed bean backing区别。如果打开速度慢,可以尝试快速版;如果想保存快照,可以添加到搜藏。
(百度和网页http://blog.csdn.net/zx870119/archive/2007/07/25/1707703.aspx的作者无关,不对其内容负责。百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面。)
--------------------------------------------------------------------------------
用人生编写程序用程序编写人生——程序人生
ぁ旋子ぁ—— zxJavazx870119
CSDN|社区|技术中心| BLOG首页|我的首页|我的文章|个人档案|联系作者|聚合||搜索|登录 18篇原创: 0篇翻译: 0篇转载: 151次点击: 1个评论: 0个Trackbacks
文章
Hibernate(RSS)
Java(RSS)
JSF(RSS)
JSP(RSS)
Spring(RSS)
Struts(RSS)
WebWork(RSS)
框架集成(RSS)
系统维护(RSS)
收藏
相册
存档
2007年07月(17)
2007年06月(1)
最近评论
wyj444698561:高手!被我发现了!交个朋友
上一篇: Java集合框架|下一篇: Hibernate先知
JSF与 Struts的区别
Struts和JSF/Tapestry都属于表现层框架,这两种分属不同性质的框架,后者是一种事件驱动型的组件模型,而Struts只是单纯的MVC模式框架,老外总是急吼吼说事件驱动型就比MVC模式框架好,何以见得,我们下面进行详细分析比较一下到底是怎么回事?
首先事件是指从客户端页面(浏览器)由用户操作触发的事件,Struts使用Action来接受浏览器表单提交的事件,这里使用了Command模式,每个继承Action的子类都必须实现一个方法execute。
在struts中,实际是一个表单Form对应一个Action类(或DispatchAction),换一句话说:在Struts中实际是一个表单只能对应一个事件,struts这种事件方式称为application event,application event和component event相比是一种粗粒度的事件。
struts重要的表单对象ActionForm是一种对象,它代表了一种应用,这个对象中至少包含几个字段,这些字段是Jsp页面表单中的input字段,因为一个表单对应一个事件,所以,当我们需要将事件粒度细化到表单中这些字段时,也就是说,一个字段对应一个事件时,单纯使用Struts就不太可能,当然通过结合JavaScript也是可以转弯实现的。
而这种情况使用JSF就可以方便实现,
<h:inputText id="userId" value="#{login.userId}">
<f:valueChangeListener type="logindemo.UserLoginChanged"/>
</h:inputText>
#{login.userId}表示从名为login的JavaBean的getUserId获得的结果,这个功能使用struts也可以实现,name="login" property="userId"
关键是第二行,这里表示如果userId的值改变并且确定提交后,将触发调用类UserLoginChanged的processValueChanged(...)方法。
JSF可以为组件提供两种事件:Value Changed和 Action.前者我们已经在上节见识过用处,后者就相当于struts中表单提交Action机制,它的JSF写法如下:
<h:commandButton id="login" commandName="login">
<f:actionListener type=”logindemo.LoginActionListener”/>
</h:commandButton>
从代码可以看出,这两种事件是通过Listerner这样观察者模式贴在具体组件字段上的,而Struts此类事件是原始的一种表单提交Submit触发机制。如果说前者比较语言化(编程语言习惯做法类似Swing编程);后者是属于WEB化,因为它是来自Html表单,如果你起步是从Perl/PHP开始,反而容易接受Struts这种风格。
基本配置
Struts和JSF都是一种框架,JSF必须需要两种包JSF核心包、JSTL包(标签库),此外,JSF还将使用到Apache项目的一些commons包,这些Apache包只要部署在你的服务器中既可。
JSF包下载地址:http://java.sun.com/j2ee/javaserverfaces/download.html选择其中Reference Implementation。
JSTL包下载在http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi
所以,从JSF的驱动包组成看,其开源基因也占据很大的比重,JSF是一个SUN伙伴们工业标准和开源之间的一个混血儿。
上述两个地址下载的jar合并在一起就是JSF所需要的全部驱动包了。与Struts的驱动包一样,这些驱动包必须位于Web项目的WEB-INF/lib,和Struts一样的是也必须在web.xml中有如下配置:
<web-app>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
</web-app>
这里和Struts的web.xml配置何其相似,简直一模一样。
正如Struts的struts-config.xml一样,JSF也有类似的faces-config.xml配置文件:
<faces-config>
<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/welcome.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>com.corejsf.UserBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
在Struts-config.xml中有ActionForm Action以及Jsp之间的流程关系,在faces-config.xml中,也有这样的流程,我们具体解释一下Navigation:
在index.jsp中有一个事件:
<h:commandButton label="Login" action="login"/>
action的值必须匹配form-outcome值,上述Navigation配置表示:如果在index.jsp中有一个login事件,那么事件触发后下一个页面将是welcome.jsp
JSF有一个独立的事件发生和页面导航的流程安排,这个思路比struts要非常清晰。
managed-bean类似Struts的ActionForm,正如可以在struts-config.xml中定义ActionForm的scope一样,这里也定义了managed-bean的scope为session。
但是如果你只以为JSF的managed-bean就这点功能就错了,JSF融入了新的Ioc模式/依赖性注射等技术。
Ioc模式
对于Userbean这样一个managed-bean,其代码如下:
public class UserBean{
private String name;
private String password;
// PROPERTY: name
public String getName(){ return name;}
public void setName(String newValue){ name= newValue;}
// PROPERTY: password
public String getPassword(){ return password;}
public void setPassword(String newValue){ password= newValue;}
}
<managed-bean>
<managed-bean-name>user</managed-bean-name>
<managed-bean-class>com.corejsf.UserBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>name</property-name>
<value>me</value>
</managed-property>
<managed-property>
<property-name>password</property-name>
<value>secret</value>
</managed-property>
</managed-bean>
faces-config.xml这段配置其实是将"me"赋值给name,将secret赋值给password,这是采取Ioc模式中的Setter注射方式。
Backing Beans
对于一个web form,我们可以使用一个bean包含其涉及的所有组件,这个bean就称为Backing Bean, Backing Bean的优点是:一个单个类可以封装相关一系列功能的数据和逻辑。
说白了,就是一个Javabean里包含其他Javabean,互相调用,属于Facade模式或Adapter模式。
对于一个Backing Beans来说,其中包含了几个managed-bean,managed-bean一定是有scope的,那么这其中的几个managed-beans如何配置它们的scope呢?
<managed-bean>
...
<managed-property>
<property-name>visit</property-name>
<value>#{sessionScope.visit}</value>
</managed-property>
这里配置了一个Backing Beans中有一个setVisit方法,将这个visit赋值为session中的visit,这样以后在程序中我们只管访问visit对象,从中获取我们希望的数据(如用户登陆注册信息),而visit是保存在session还是application或request只需要配置既可。
UI界面
JSF和Struts一样,除了JavaBeans类之外,还有页面表现元素,都是是使用标签完成的,Struts也提供了struts-faces.tld标签库向JSF过渡。
使用Struts标签库编程复杂页面时,一个最大问题是会大量使用logic标签,这个logic如同if语句,一旦写起来,搞的JSP页面象俄罗斯方块一样,但是使用JSF标签就简洁优美:
<jia:navigatorItem name="inbox" label="InBox"
icon="/images/inbox.gif"
action="inbox"
disabled="#{!authenticationBean.inboxAuthorized}"/>
如果authenticationBean中inboxAuthorized返回是假,那么这一行标签就不用显示,多干净利索!
先写到这里,我会继续对JSF深入比较下去,如果研究过Jdon框架的人,可能会发现,Jdon框架的jdonframework.xml中service配置和managed-bean一样都使用了依赖注射,看来对Javabean的依赖注射已经迅速地成为一种新技术象征,如果你还不了解Ioc模式,赶紧补课。
好了,文章到此结束,希望可以帮助到大家。