摘 要: JavaServer Faces的工作原理及运用JSF开发Web应用程序的一个简单实例。
关键词: JSF技术 MVC模式 JSP技术 Web应用程序
JSF(Java Server Faces)是SUN公司为了方便Web应用程序的设计,使应用程序逻辑设计和界面设计脱耦而提出的一种用户界面程序框架(UI Framework)。它包括一组API和二个自定义标记库,用于UI组件的表示、组件状态的管理、客户端事件的处理、输入的验证以及页面导航的管理等。与传统的Servlet和JSP技术相比,JSF能使Web应用程序在UI的开发上更具扩充性和维护性,它有助于Web应用程序的开发人员角色分离。JSF1.0已经被SUN公司纳入到最新的J2EE1.4 SDK中。
1 JSF出现的背景和技术优势
使用Java开发Web应用程序经历了几个发展阶段。一开始是使用Servlet,直接利用request和response对象接收和响应客户端的请求。Servlet的一个显著缺点是需要在Java代码中嵌入大量的标记语言(如HTML),处理逻辑和显示逻辑严重耦合,非常不利于程序的维护和界面的设计。基于这种情况,SUN又发展了JSP技术。与Servlet正好相反,JSP是在标记语言中嵌入Java代码,但它仍没有实现Web开发角色的分离,美工设计人员仍然要在一堆混杂脚本、标记和Java程序的代码中工作,不利于程序的维护。后来,JSP加入了Tab library机制,鼓励开发人员使用自定义标签封装业务逻辑,JSP页面尽可能只出现各种标签。大量自定义JSP标签的出现,并经过SUN公司的标准化后,形成了JSTL(Java Standard Tab Library)。JSTL技术基本实现了页面逻辑和显示逻辑的脱耦,方便了Web的各种开发人员。随着Web应用程序规模的不断扩大,MVC-Model2体系的概念越来越适用于Web应用程序的开发。经过大量实践的检验,它已经成为最适合开发Web应用程序的模板。
遵循MVC-Model2架构开发的应用程序框架(Framework)已有不少,例如当今比较流行的Struts、Tapestry、Turbine等。JSF的出现并不是要代替这些框架,相反,由于技术的着重点不同,JSF可以和这些Framework很好地协同工作。JSF基于JSTL技术,着力于解决现有框架不能完成的难题,例如View和Model无法实现完全脱耦、客户端种类繁多等。JSF是真正彻底的MVC(Model View Controller),图1为JSF的MVC架构。
JSF的技术重点在View部分,它实现了Web应用程序设计角色的完全分离。JSF网页设计者只需要专注于页面的设计;应用程序开发者主要关心Model部分的JavaBean的开发,例如连接JNDI、进行数据持久化或调用EJB等;程序的流程控制则由faces-config.xml专门配置。
JSF还可以根据不同的客户端标记语言做相应的调整,例如HTML、XUL、XMLForm、Xforms和WML等,使Web应用程序能在最小的改动下适应不同的客户端类型,如图2所示。
其中JSF Core Library负责基本程序的运行,包括程序运行生命期控制、事件处理等。RenderKit把服务器端的UI组件转化成任何一种使用者界面标准,支持众多的标记语言。
图3为一个JSF网页的生命周期。只有送给java.faces.webap.FacesServlet控制器的HTTP请求才进入这个生命周期。在阶段1,系统根据JSF网页的内容建立一个组件树,根据组件树中每个组件的设定将对应的转换器(Converter)、验证器(Validator)以及事件处理函数(Event Handler)与特定组件关联,在阶段2中系统根据HTTP request的参数一一调用这些组件;然后分别在阶段3、4和5中执行参数验证、模型更新和事件处理;最后系统调用组件相应的方法将它们转化成适当的标签(HTML或者WML等)送到客户端。
2 JSF应用的一个简单实例
本例展现了使用JSF框架设计Web应用程序的步骤。程序功能是让用户在浏览器中输入用户名和密码登录,系统执行验证后返回登录结果。关于基于JSF的详细开发,可以参考文献[3]和文献[4]。
2.1 视图设计
视图(View)部分包括login.jsp和response.jsp文件。前者是一个可以让用户输入登录名、密码进行登录的页面,后者用于返回用户的登录结果。所有的JSP文件都要加入以下二行,以引入JSF的自定义标记库:
<%@ taglib uri=″http://java.sun.com/jsf/html″prefix=″h″%>
<%@ taglib uri=″http://java.sun.com/jsf/core″prefix=″f″%>
其中login.jsp文件的主要代码如下:
<f:view>
<h:form id=″loginform″>
<h2>Please enter your username and password</h2>
username:
<h:inputText id=″input_username″value=″#{userBean.username}″required=″true″/></br><!--把输入的信息放入模型(javabean)--!>
<h:message for=″input_username″/></br>
password:
<h:inputSecret id=″input_password″value=″#{userBean.password}″required=″true″>
<f:validateLength minimum=″6″/> <!--这是一个JSF内置的验证器,用于校验输入的合法性,这里不允许用户输入低于6位长度的密码--!>
</h:inputSecret></br>
<h:message for=″input_password″/></br><!--在这里显示校验出错信息--!>
<h:commandButton id=″submit″action=″go″value=″Submit″/><!--在faces-config.xml文件中定义go行为的处理--!>
</h:form>
</f:view>
注释部分说明了View是如何与Model和Controller关联的。
2.2 模型设计
JSF的模型主要用JavaBean来实现,这里定义了一个ValUser.java作为JavaBean,用于存储和处理页面传送的信息。
package myjsf;
public class ValUser{
public ValUser( ) { }
String username=null;
String password=null;
//此处省略bean属性username和password的getter
//和setter方法
// ……
String resultMessage=null;
public String getResultMessage( )//返回登录结果
{
if (isValid( ))
this.resultMessage=″valid user,welcome″;
else
this.resultMessage=″invalid user,please login again″;
return this.resultMessage;
}
public void setResultMessage(String resultMessage)
{ }
private boolean isValid( )//检验用户名密码是否合法
{
if (this.password.trim( ).equals(″123456″))
return true;
else
return false;
}
}
为了方便说明,这里简单地定义用户输入123456就是合法登录。实际应用中,应该使用JDBC或其他技术从数据持久层获取该用户的密码进行验证。这个JavaBean定义了三个属性,其中username和password从login.jsp中获取值,resultMessage用于向response.jsp页面反馈登录结果。
2.3 控制器设计和配置文件
JSF的控制器设计是在配置文件中完成的。首先需要配置Web应用程序的web.xml文件,加入以下内容:
<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>/login/*</url-pattern>
</servlet-mapping>
以上内容表示只有对相对路径在login下的页面请求才交给JSF控制器处理,其他请求则不经过该控制器(图3)。JSF本身的控制文件是faces-config.xml,其中的navigation-rule节点定义了页面跳转流程控制,managed-bean节点定义了JavaBean的信息等,这里不再详述。
3 结 论
JSF框架较好地贯彻了MVC-Model2设计体系的思想,使页面表示和商业逻辑脱耦,让各类Web应用程序开发角色实现真正的各司其职。同时,JSF支持不同的客户端应用,使Web应用程序可以很容易地适应不同的客户端访问协议。JSF比较适合开发大型的Web应用程序。由于配置过程比较繁琐,待支持JSF的集成开发工具或插件发展成熟时,开发基于JSF的Web应用程序将会变得十分轻松和自然。
参考文献
1 Sun Microsystems.JavaServer Faces Technology Overview. http://java.sun.com/j2ee/javaserverfaces/
2 Gamma E,Helm R,Johnson R et al.Design Patterns:Elements of Reusable Object-Oriented Software.Addison Wesley,1995
3 Sun Microsystems.JavaServer Faces in The J2EE 1.4 Tutorial.http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JSFIntro. html
4 Bergsten H.JavaServer Faces.O′Reilly&Associates,2004