FAQ:
1. JSF跟Spring如何结合?
A: 通过在faces-config配置文件中加入
<application>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
可以使JSF跟Spring结合。
2. 为何称JSF是基于event的?而Struts是基于请求驱动或者Command驱动。
A: JSF是以页面组件为中心的,而页面组件是面向事件的。JSF只有commandButton,commandLink这两个UI组件是基于事件的,可以设定action属性,而该属性便是调用后台managed-bean的对应方法。
不过ASP.NET是所有UI组件都是面向事件的。
而其他UI组件,可以通过设定value属性,来调用后台managed-bean的对应方法,获取其返回值。例如:
<h:outputText value="#{testBean.creationTime}"/>
如果获取的返回值是一个自定义类型或者List,如何进行取自定义类型的属性或者迭代?
可以通过类似EL(称为JSF-EL)的方式来获取嵌套属性的值。可以通过#{purchases.cheapItems[2]}或者
#{purchases.valuableItems["low"]}获取List的值。
3. JSF的访问路径的机制?
A: JSF是以页面组件为中心的,类似ASP.NET。所以要访问JSF的应用,实际上是直接访问JSP页面。不过对xx.jsp的访问路径要修改成xx.faces。(类似ASP.NET去访问xx.aspx)
4. JSF是否有interceptor等拦截器机制?如何在managed-bean中使用Servlet的API?
A: JSF可以在页面增加actionListener,类似interceptor的机制。
Servlet的API可以通过FacesContext,例如:
FacesContext fc = FacesContext.getCurrentInstance();
fc.getExternalContext().getResponse();
fc.getExternalContext().getRequest();
5. JSF可否结合其他JSP标签?结合ajax是否方便?在页面层结合Scriptlet是否方便,可否跟request的Attribute等结合使用?
A: JSF可以使用其他JSP标签以及JSTL。JSF通过EL取值和通过JSF-EL取值是效果一样的。例如
<LI>Employee's first name: ${employee.name.firstName}
跟<LI>Employee's first name: <h:outputText value="#{employee.name.firstName}"/> 作用一样。
JSF后台managed-bean的返回值实际上是放在request的Attrubite中,key为其属性名。所以可以直接在JSP的Scriptlet中与request的Attribute等结合使用。
6. JSF的MVC框架与Struts框架的异同?
A: JSF的MVC框架跟ASP.NET类似,是以页面组件为中心的。 要先访问指定的jsp相关的faces然后再跳转到Controller最后再到View。如下图所示:
Struts的MVC框架是 Controller(action)->View(JSP)
JSF的MVC框架是 View(*.faces)->Controller(managed-bean)->View(JSP)
7.JSF能否实现类似Struts的 action(or servlet)->view(JSP)?跟.faces相关的jsp能否隐藏起来?
A: 都不能。
8.JSF的<managed-bean>可以实现对actionBean的设值注入。
9.配置文件的分离,通过在web.xml中设置
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config-beans.xml,/WEB-INF/faces-config-nav.xml</param-value>
</context-param>
10.JSF跟ASP.NET的一些区别。
ASP.NET页面控件的name跟id 是跟自命名是一致的。例如:
<input name="TextBox1" type="text" value="ss" id="TextBox1" />
11.JSF如何传递页面参数?
A: 通过<h:commandLink action="viewProduct" styleClass="highLightLink">
<h:outputText value="view"/>
<f:param name="productId" value="#{productBean.id}"/>
</h:commandLink>
这种方式是通过post来传递参数的。对于url参数只能在backingBean中,通过如下代码获取
FacesContext fc = FacesContext.getCurrentInstance();
String id = (String) fc.getExternalContext().getRequestParameterMap().get("id");
JSF的优缺点:
我认为JSF的优缺点都是因为这个框架是以页面组件为中心。
优点:可以利用一些功能强大的UI组件,这些UI组件是服务器端,并且基于事件的。可以方便地定义事件响应方法。
缺点:太依赖于UI组件。目前尚没有可以跟vs.net媲美的IDE来支持基于UI组件的开发。所以开发和配置起来还是有些麻烦,而且开发自定义的UI组件更加复杂。
因为依赖于UI组件,所以页面层的开发不够灵活。
因为依赖于UI组件,所以很多原始的html标签不能用。这导致美工设计的静态页面,到程序员这边还要经过不小的调整,而不像其他web框架那样结合方便。
JSF的标准标签包括以下几个类别:
输出(Outputs)
其名称以output作为开头,作用为输出指定的讯息或绑定值。
输入(Inputs)
其名称以input作为开头,其作用为提供使用者输入字段。
命令(Commands)
其名称以command作为开头,其作用为提供命令或连结按钮。
选择(Selections)
其名称以select作为开头,其作用为提供使用者选项的选取。
其它
包括了form、message、messages、graphicImage等等未分类的标签。
JSF的页面组件的属性中,都没有name这个属性。 这些标准标签都可以设定id、styleClass等属性值。
如果自定义JSF的页面组件,一般会用到以下的类:
javax.faces.component.UIComponent
自定义Component所要继承的父类别,但通常,您是继承其子类别,例如UIInput、UIOutput等等。
javax.faces.webapp.UIComponentTag
自定义JSF标签所要继承的父类别,继承它可以帮您省去许多JSF标签处理的细节。
javax.faces.context.FacesContext
包括了JSF相关的请求信息,您可以透过它取得请求对象或请求参数,或者是Application对象。
javax.faces.application.Application
包括了一个应用程序所共享的信息
如果安装了myeclipse,jsp页面中只要包含有jsf的taglib(如下所示),则会自动打开JSF的Designer
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
JSF跟Struts2的整合
JSF可以跟Struts2进行整合,具体参考《Struts 2权威指南》
后台可以使用Struts2的Action类,这些类因为可以有Spring来管理,更具有可测试性。
前台页面依旧使用JSF的页面组件。
只要加入struts2和jsf的lib包以及struts2-jsf-plugin-2.**.jar
然后简单修改web.xml以及在struts.xml中加入相应的interceptors即可,而不需要faces-config.xml配置文件。
<package name="jsf" extends="jsf-default">
<interceptors>
<interceptor-stack name="jsfFullStack">
<interceptor-ref name="params" />
<interceptor-ref name="basicStack"/>
<interceptor-ref name="jsfStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="jsfFullStack"/>
</package>