首页编程java编程javax.faces是什么,如何使用FacesContext类

javax.faces是什么,如何使用FacesContext类

编程之家 2023-10-10 120次浏览

老铁们,大家好,相信还有很多朋友对于javax.faces是什么和如何使用FacesContext类的相关问题不太懂,没关系,今天就由我来为大家分享分享javax.faces是什么以及如何使用FacesContext类的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!

javax.faces是什么,如何使用FacesContext类

uidata是什么

猪哥解答:

UI知道吧,UI界面这个名词如果不懂的话百度一下,Data你也应该知道是什么意思,连起来UIData可以理解为页面数据,页面的Table、Tree什么的可以用UIData来封装处理,下面给你转一个实例,也许会对你有帮助。

猪哥转帖:

javax.faces是什么,如何使用FacesContext类

UIData:表示数据集合,每个数据项由DataModel(标准JSF UIComponent Model Bean之一)的一个实例封装。该组件通常用来渲染表格、列表和树。

实例:

新建一个实体bean

javax.faces是什么,如何使用FacesContext类

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模式,赶紧补课。

好了,文章到此结束,希望可以帮助到大家。

陆冠英(陆冠英的父亲) javacore用什么看,java core