Java Server Face是快速开发web应用的一个框架和解决方案。他改变了以往基于java web应用的request-response处理机制,采用了事件驱动处理机制。这为在java平台上快速开发web应用提供了可能。JSF框架简化了web form有效性检查、request参数解析,状态管理,多线程支持等任务。开发人员只需实现具体的事件处理器和事务逻辑(在JSF中分别称为Handlers和Components)。<o:p></o:p>
在采用JSF框架进行开发时,不需要继承实现JSF的任何API,应用各组件之间的关系通过一个XML(faces-config.xml)配置文件实现。他的实现方式与以往介绍过的Spring框架有些类似。<o:p></o:p>
Java Server Face与MVC架构比较<o:p></o:p>
与现在较为流行的MVC 架构有所不同,JSF在设计结构上并没有将视图和逻辑事务严格的分开,而是依赖于程序设计人员的具体实现。比如Handlers和Components在 实际的开发中可以在一个类中实现,这样就会使视图层和逻辑处理层紧密的偶合在一起。建议在进行JSF项目时应严格要求程序设计人员将Handlers和 Components分离。<o:p></o:p>
<o:wrapblock><v:shapetype coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f" id="_x0000_t75"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></v:path><o:lock v:ext="edit" aspectratio="t"></o:lock></v:shapetype></o:wrapblock>
以下是MVC(以Struts为例)和JSF框架在结构设计上的比较<o:p></o:p>
<o:p></o:p>
从上图可以看出,MVC和JSF的开发结构有很大的区别。MVC主要关注于开发应用各层的松散偶合;JSF则关注于事件处理。从应用上分析,MVC重视结构的划分而JSF致力于为快速开发提供基础解决方案。笔者建议不能简单的比较两种架构的优劣,应结合实际的开发和应用选择。<o:p></o:p>
Java Server Face的技术实现<o:p></o:p>
JSF框架的实现依赖于以下几种技术:Java Tag Lib,IoC type2(setter and getter),xml
在JSF的表示层使用Tag lib技术处理web的form object
使用IoC type2和xml将form object和具体的handler和component关联起来
Java Server Face的示例<o:p></o:p>
示例应用需求说明:实现一个用户管理功能,要求将视图层、逻辑层、数据访问层分开,降低各层的偶合度。<o:p></o:p>
<o:wrapblock><v:shape type="#_x0000_t75" style="margin-top: 18.2pt; z-index: 2; left: 0px; margin-left: 0px; width: 415.5pt; position: absolute; height: 430.5pt; text-align: left;" id="_x0000_s1027"><v:imagedata src="file:///F:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msoclip1/04/clip_image003.wmz" o:title=""></v:imagedata><w:wrap type="topAndBottom"></w:wrap></v:shape></o:wrapblock>
下图是示例的简单类图,其中数据层采用DAO+Hibernate技术<o:p></o:p>
<o:p></o:p>
UserForm代码:<o:p></o:p>
package jsfdemo.forms;<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
/**<o:p></o:p>
* Created date:2004-8-19<o:p></o:p>
* @author genstone<o:p></o:p>
*<o:p></o:p>
*/<o:p></o:p>
public class UserForm<o:p></o:p>
{<o:p></o:p>
private String username;<o:p></o:p>
private Long userid;<o:p></o:p>
private String password;<o:p></o:p>
<o:p></o:p>
/**<o:p></o:p>
* @return Returns the username.<o:p></o:p>
*/<o:p></o:p>
public String getUsername()<o:p></o:p>
{<o:p></o:p>
return username;<o:p></o:p>
}<o:p></o:p>
/**<o:p></o:p>
* @param username The username to set.<o:p></o:p>
*/<o:p></o:p>
public void setUsername(String username)<o:p></o:p>
{<o:p></o:p>
this.username = username;<o:p></o:p>
}<o:p></o:p>
/**<o:p></o:p>
* @return Returns the password.<o:p></o:p>
*/<o:p></o:p>
public String getPassword()<o:p></o:p>
{<o:p></o:p>
return password;<o:p></o:p>
}<o:p></o:p>
/**<o:p></o:p>
* @param password The password to set.<o:p></o:p>
*/<o:p></o:p>
public void setPassword(String password)<o:p></o:p>
{<o:p></o:p>
this.password = password;<o:p></o:p>
}<o:p></o:p>
/**<o:p></o:p>
* @return Returns the userid.<o:p></o:p>
*/<o:p></o:p>
public Long getUserid()<o:p></o:p>
{<o:p></o:p>
return userid;<o:p></o:p>
}<o:p></o:p>
/**<o:p></o:p>
* @param userid The userid to set.<o:p></o:p>
*/<o:p></o:p>
public void setUserid(Long userid)<o:p></o:p>
{<o:p></o:p>
this.userid = userid;<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
UserHandler代码:<o:p></o:p>
package jsfdemo.handlers;<o:p></o:p>
<o:p></o:p>
import jsfdemo.components.BaseComponent;<o:p></o:p>
<o:p></o:p>
/**<o:p></o:p>
* Created date:2004-9-20<o:p></o:p>
* @author genstone<o:p></o:p>
*<o:p></o:p>
*/<o:p></o:p>
public class UserHandler<o:p></o:p>
{<o:p></o:p>
private BaseComponent component;<o:p></o:p>
<o:p></o:p>
/**<o:p></o:p>
* @return Returns the component.<o:p></o:p>
*/<o:p></o:p>
public BaseComponent getComponent()<o:p></o:p>
{<o:p></o:p>
return component;<o:p></o:p>
}<o:p></o:p>
/**<o:p></o:p>
* @param component The component to set.<o:p></o:p>
*/<o:p></o:p>
public void setComponent(BaseComponent component)<o:p></o:p>
{<o:p></o:p>
this.component = component;<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
public void save()<o:p></o:p>
{<o:p></o:p>
component.save();<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
public void delete()<o:p></o:p>
{<o:p></o:p>
component.delete();<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
public void modify()<o:p></o:p>
{<o:p></o:p>
component.modify();<o:p></o:p>
}<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
UserComponent代码:<o:p></o:p>
package jsfdemo.components;<o:p></o:p>
<o:p></o:p>
<o:p></o:p>
import net.sf.hibernate.HibernateException;<o:p></o:p>
<o:p></o:p>
import jsfdemo.beans.UserInfo;<o:p></o:p>
import jsfdemo.daos.BaseDAO;<o:p></o:p>
import jsfdemo.forms.UserForm;<o:p></o:p>
import jsfdemo.util.ValueObejctUtil;<o:p></o:p>
import util.Logger;<o:p></o:p>
<o:p></o:p>
/**<o:p></o:p>
* Created date:2004-9-20<o:p></o:p>
* @author genstone<o:p></o:p>
*<o:p></o:p>
*/<o:p></o:p>
public class UserComponent implements BaseComponent<o:p></o:p>
{<o:p></o:p>
private UserForm userForm =null;<o:p></o:p>
private BaseDAO dao = null;<o:p></o:p>
<o:p></o:p>
/**<o:p></o:p>
* @return Returns the userForm.<o:p></o:p>
*/<o:p></o:p>
public UserForm getUserForm()<o:p></o:p>
{<o:p></o:p>
return userForm;<o:p></o:p>
}<o:p></o:p>
/**<o:p></o:p>
* @param userForm The userForm to set.<o:p></o:p>
*/<o:p></o:p>
public void setUserForm(UserForm userForm)<o:p></o:p>
{<o:p></o:p>
this.userForm = userForm;<o:p></o:p>
}<o:p></o:p>
<o:p></o:p>
public boolean save()<o:p></o:p>
{<o:p></o:p>
UserInfo info = ValueObejctUtil.getPersistObject((UserForm)userForm);<o:p></o:p>
try<o:p></o:p>
{<o:p></o:p>
//insert into database<o:p></o:p>
info.userid = (Long)dao.save(info);<o:p></o:p>
}<o:p></o:p>
catch (HibernateException e)<o:p></o:p>
&n