`

Struts2中整合JSF

阅读更多
1,JSF简介

JSF是Sun公司提出的一种新的MVC规范,作为JEE规范的组成部分,并且随着JDK一起发布,从某种程序上看,JSF已经起出了传统MVC框架,非常类似于ASP.NET服务器组件的概念.严格地说,JSF并不是一个框架而是一种规范,它是JEE5.0的重要组成部分,它通过提供一种页面组件的方式,隐藏了传统Web应用开发的HTTP细节,允许开发者以传统桌面编程的方式来开发Web应用,JSF通过将后台Bean(作用等同于控制器)的属性,方法直接绑定到页面组件的value属性或者action属性,就可以非常方便地实现系统MVC控制.

Struts2提供了良好的可扩展性,借助于Struts2的JSF插件,Struts2可以实现与JSF的整合,一旦完成了Struts2和 JSF的整合,我们就可以在Struts2的JSP页面中使用JSF页面组件,并用Action来模拟JSF的后台Bean,将JSP页面的JSF组件绑定到Action属性,从而允许开发者以JSF的方式来开发Struts2应用.

JSF是一种规范,当Sun公司提出JSF规范的同时,也提供了JSF的一个参考实现(Reference Implementation,简称RI).apache也提供了JSF的另一个实现,就是MyFaces框架,目前不管是JSF RI还是MyFaces框架,都已经逐渐成熟起来,完全可作为实现项目中的MVC框架.

当Microsoft推出ASP.NET开发平台后,ASP.NET开发平台里包含了一种服务器组件概念,通过使用服务器组件,开发者能以一种开发桌面应用的方式来开发Web应用,但Web应用程序的开发与桌面应用的开发在本质上存在着太多的差异,Web应用的开发人员必须处理HTTP的细节,而且 Web应用是由一个一个页面组成,每个页面之间的信息是不连续的,是无状态的,但传统桌面程序本质上是由一个程序不断地驱动其他程序,因些各程序之间的信息是连续的.而Microsoft的ASP.NET极好地简化了Web应用的开发,在ASP.NET的服务器组件里,开发者可以直接调用服务器组件方法来取得服务器组件的值----看起来已经超出了传统Web应用的请求---响应模式.

JSF引入了大量全新的标签库,这套标签库看起来就像是普通的HTML标签一样,但它不是静态的,而是动态的.对于网面开发人员而言,使用JSF标签库与使用变通HTML标签库并没有太大的差别,网页开发人员无需理会JSF标签后端的动态部分;网页设计人员无需了解JAVA知识,甚至无需接触 JSTL这种标签库,也可以动态展现数据.对于应用程序设计人员而言,JavaServer Faces提供一个与桌面应用开发相似的模型,我们完全可以采用基于事件的编程模型,而不是请求---响应编程模型,因此避免了出现HTTP细节的问题.

从前面的介绍中可以看出,JSF已经是一个完整的MVC框架,JSF的核心就是事件驱动,类似于早期的Visual Basic编程模式,可以通过为页面中的按钮单击事件,输入框的内容改变事件提供事件响应程序来实现Web应用流程.

JSF的组件和标签的封装程度非常高,很多典型应用已经不需要开发者去处理HTTP细节了,页面操作也会被自动映射到后台的JavaBean中,处理逻辑直接访问后台的JavaBean(Back Bean也就是控制器)交互.此外,JSF提供的组件标签(非常类似于ASP.NET的服务器组件的概念),封装程度相当高,而且有很简单的编程模式,JSF的事件模型可以细化到表单里每个表单域.JSF直接使用POJO作为控制器,并且可以使用任何方法来处理用户请求.相对于 Struts2,JSF还有一个显著的优势在于丰富的组件标签,这些组件标签提供了一种事件驱动的编程模式,可以大大简化应用的开发.

从以上两者的对比可以看出Struts2和JSF有各自的优势:
Struts2更接近传统的Web编程流程,使用更加方便.
JSF的组件库能提供细致的事件模型,而且可以简化Web应用的开发.

2,使用MyFaces

通常认为JSF RI比较权威,是官方的参考实现,但过于古板,提供的组件库不够丰富;MyFaces在完全实现了JSF RI的基本功能之外,还提供了许多额外的组件库,因此在实际开发中有很大的吸引力.因此我这里使用MyFaces.

2.1 下载和安装MyFaces

MyFaces除了实现JSF RI的基本功能外,还包含了一个tomahawk额外库,这个库内包含了更多的组件,借助于tomahawk的帮助,可以提供更多页面组件.MyFaces的下载和安装请按如下步骤进行:
1,下载MyFaces必需的核心类库,登陆http://myfaces.apache.org/download.html页面,下载MyFaces的最新版本,我这里用的是MyFaces Core 1.2.3 Distribution,如果需要使用tomahawk额外标签库,则还要下载tomahawk部分.tomahawk的下载链接也可以在这个页面找到.我下载的是myfaces-core-1.2.3-bin.zip文件
2,将下载的文件\lib下的所有JAR文件复制到WEB-INF\lib目录下,此时就可以在Web应用中使用MyFaces框架了.
3,为了可以编译MyFaces程序,建议将myfaces-api-1.2.3.jar添加到JDK的环境变量classpath里,当然也可以使用 ant工具.
4,在Web应用中安装MyFaces标签库,安装MyFaces标签库根据所用的Servlet容器不同,可能会有两种做法:
对于使用支持Servlet2.4以上规范的Web容器,我们无需修改web.xml文件,如果希望在JSP页面中使用MyFaces标签库,则可以直接在JSP页面中使用如下两行来导入MyFaces标签库:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
这里看起来很奇怪,我们为什么导入的是JSF标签库而不是MyFaces的标签库呢?熟悉自定义标签库规范就知道,此处的URI只是定义标签库时指定的 URI,与实现的内容并没有必须的联系.
MyFaces的标签库文件是放在myfaces-impl-1.2.3.jar文件夹的META-INF路径下的,对于使用Servlet2.4以上规范的Web应用,会自动读取JAR文件里的TLD文件,并识别到其中的URI信息.
如果使用更早的Servlet规范的Web应用,则应该在web.xml文件中增加如下配置片段:
<taglib>
<taglib-uri>http://java.sun.com/jsf/html</taglib-uri>
<taglib-location>/WEB-INF/lib/myfaces-impl-1.2.3.jar</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jsf/core</taglib-uri>
<taglib-location>/WEB-INF/lib/myfaces-impl-1.2.3.jar</taglib-location>
</taglib>

2.2 从输入页面开始

前面已经增加了MyFaces的标签库定义,所以现在可以在JSP页面使用MyFaces标签库了,如果要查看各标签库详细信息,请参看 MyFaces下tlddoc路径下的API文档.下面是一个例子的页面代码:
<%@ 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" %>
<!--该句绑定在classes下的messages的资源文件-->
<f:loadBundle basename="messages" var="msg"/>
<html>
<head>
<title>登陆</title>
</head>
<body>
<!-- 开始使用JSF的视图输出 -->
<f:view>
   <h3>
    <!-- 输出国际化资源文件中的国际化信息 -->
    <h:outputText value="#{msg.loginHeader}"/>
   </h3>
    <!-- 输出login Bean类的err属性的内容 -->
   <b><h:outputText value="#{login.err}"/></b>
   <h:form id="loginForm">
    <h:outputText value="#{msg.namePrompt}"/>
    <!-- 将下面单行输入框的值绑定到login Bean类的name属性 -->
    <h:inputText value="#{login.name}" /><br>
    <h:outputText value="#{msg.passPrompt}"/>
    <h:inputText id="pass" value="#{login.pass}"/>
    <br>
    <!-- 将下面按钮的动作绑定到login Bean类的valid方法 -->
    <h:commandButton action="#{login.valid}" value="#{msg.buttonTitle}" />
   </h:form>
</f:view>
</body>
</html>
从上面的页面代码中可以看到,MyFaces的输入页面已经不再是传统的HTML页面,它几乎完全使用了MyFaces标签来生成页面效果,这些 MyFaces标签对应一个又一个的页面组件,而这些页面组件刚会生成与之对应的HTML标签.

使用MyFaces标签时,已经不再是传统的为表单指定action属性,用于设置表单提交的URL,页面将每个表单域绑定到后台Bean的方法, 从而将页面的视图组件与后台的Bean实现关联.

在浏览器中http://localhost:8080/jsfqs/浏览该页面,可以看到变通的HTML页面的效果,表面上看来这个页面非常简单,我们通过查看生成的HTML的源代码,发现该表单的代码非常复杂,而且该表单包含了一个隐藏域,这个隐藏域通常是如下形式的的代码:
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="rO0ABXVyABNb..." />
上面隐藏域的value值通常非常长,而且在我们看来完全是一堆乱码,但这正是MyFaces实现客户端保存状态的关键,MyFaces解决了Web应用状态不连续的弊端,它将客户端状态通过隐藏域的形式保存下来,但开发者无需处理这些细节,因而提供了更好的封装.

2.3 在Web应用中配置MyFaces

前面的JSP页面已经不再是传统的HTML页面了,该页面中的表单域是直接绑定到后台Bean的,因些直接浏览该页面是无法看到正常结果的(没有 MyFaces框架的参与,就不可能实现业务组件和后台Bean的绑定),为了让MyFaces能对每个JSP页面进行处理,下面将MyFaces的 FacesServlet部署在Web应用中,下面是在web.xml文件中配置FacesServlet的配置片段:
    <!-- 配置MyFaces的FacesServlet -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 配置Faces Servlet Mapping映射 -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
从上面的配置片段中可以看到,所有以JSF作为后缀的请求都会先经过FacesServlet的处理,FacesServlet就会把JSP页面中的表单域与后台Bean的属性或方法关联起来.此外,如果MyFaces需要使用多个配置文件(用于配置导航规则和后台Bean),那么还需要在web.xml 文件中指定JSF配置文件的位置,MyFaces推荐managed-bean(后台Bean)和navigation-rules分开配置,因此,MyFaces通常会有多个配置文件,多个配置文件之间以英文逗号(,)隔开,配置文件是根据ServletContext中的 javax.faces.CONFIG_FILES参数查找,即在web.xml文件中增加如下一段:
<!-- 指定MyFaces的配置文件的路径 -->
    <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>
经过上面步骤后,还应该指定页面之间的程序状态应该保存在哪里,可以选择保存在客户端,也可以选择保存在服务器端,配置程序状态的保存位置通过如下配置片段完成:
<!-- 配置MyFaces程序状态的保存位置 -->
    <context-param>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
因为选择将程序状态保存在客户端,所以看到在客户端的表单元素增加了一个隐藏域,该隐藏域的值就是程序状态.

2.4 实现后台Bean

从作用上看,后台Bean非常类似Struts2的Action,但作用模式完全不同,对于Struts2的Action而言,应用通过表单提交方式提交Struts2的Action;但对于MyFaces的后台Bean而言,系统直接将MyFaces标签绑定到后台Bean的属性或方法.本应用的后台Bean的代码如下:
package lee;
public class LoginBean
{
    private String name;
    private String pass;
    private String err;
public void setName(String name)
{
   this.name = name;
}
public String getName()
{
   return this.name;
}
public void setPass(String pass)
{
   this.pass = pass;
}
public String getPass()
{
   return this.pass;
}
public void setErr(String err)
{
   this.err = err;
}
public String getErr()
{
   return this.err;
}

public String valid()
{
   if (name.equals("scott") && pass.equals("tiger"))
   {
    return "success";
   }
        setErr("您的用户名和密码不符合");
   return "failure";
}
}
上面的后台Bean完全是一个POJO,处理用户请求的valid方法名也可以是任意的,只要该方法可以返回一个字符串.完成后台Bean之后,还必须使用配置文件来配置该后台Bean,配置后台Bean使用标准MyFaces配置文件完成,配置该后台Bean的代码/WEB-INF/faces- config-beans.xml如下:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
    <!--配置用户bean-->
    <managed-bean>
        <managed-bean-name>login</managed-bean-name>
        <managed-bean-class>lee.LoginBean</managed-bean-class>
   <!-- 设置后台Bean实例的有效范围 -->
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
</faces-config>

2.5 定义导航规则

MyFaces以导航规则来决定资源的流向,导航规则指定了从某个页面开始,以该页面的提交按钮绑定的值作为逻辑视图,导航规则定义了这些逻辑视图和实际视图资源之间的对应关系.配置文件/WEB-INF/faces-config-nav.xml内容如下:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
    <navigation-rule>
        <!--如果执行inputname.jsp的结果是success,则从视图页inputname.jsp到视图页greeting.jsp -->
   <!-- 导航规则的输入页面 -->
        <from-view-id>/login.jsp</from-view-id>
        <navigation-case>
            <from-outcome>success</from-outcome>
            <to-view-id>/greeting.jsp</to-view-id>
        </navigation-case>
        <navigation-case>
            <from-outcome>failure</from-outcome>
            <to-view-id>/login.jsp</to-view-id>
        </navigation-case>
    </navigation-rule>
</faces-config>
从上面的分析可以看出,MyFaces的页面标签比传统的表单提交更加灵活,在传统的Web应用里,每个表单对应一次事件,当表单提交时触发submit 事件,而单个表单域则无法单独触发事件(除非使用JavaScript技术).而MyFaces则允许每个表单域单独触发事件,MyFaces允许表单域触发两类事件:
1,Value Changed:检测表单域的值的改变,当表单域值改变时,触发事件.
2,Action:表单提交时触发事件.

MyFaces还包含了IoC(依赖注入)等高级内容,这里因为主要介绍JSF和Struts2的整合,因些这里对这些内容提要不作详细介绍.

3, 安装JSF插件

借助于JSF插件的支持,Struts2可以使用JSF的页面组件,并通过Struts2的Action模拟JSF的后台Bean,也支持JSF页面组件绑定到Action属性,从而模拟一种JSF的MVC方式.

JSF插件能把JSF的每个阶段的生命周期转换成相应的Struts2拦截器,JSF插件包含了一个jsfStack拦截器栈,这个拦截器栈用于执行JSF生命周期过程,当整个构成执行结果后,Action返回一个字符串,这个字符串常量就是逻辑视图.JSF插件将JSF生命周期分解成几个拦截器和一个名为jsf的Result,因此,为了使用JSF插件,我们必须将jsfStack的拦截器栈添加到原来的拦截器栈中,并且允许配置类型为jsf的 Result.

安装JSF插件按如下步骤进行:
1,为了在Struts2应用中使用JSF组(实际上使用MyFaces组件,因为MyFaces是JSF的一个实现),必须将MyFaces的lib路径下所有的JAR文件都复制到Web应用的WEB-INF\lib\路径下.
2,将Struts2框架的lib路径下的struts2-jsf-plugin-2.0.11.2.jar文件复制到Web应用的WEB- INF\lib\路径下.
3,还需要修改web.xml文件,在该文件中增加MyFaces的支持,正如前面在web.xml文件中配置FacesServlet处理了所有以*.jsf结尾的请求,此时则应该改为处理所有以*.action结尾的请求,因此需要在web.xml文件中增加如下片段:
<!-- JavaServer Faces Servlet Configuration, not used directly -->
<servlet>
   <servlet-name>faces</servlet-name>
   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

<!-- JavaServer Faces Servlet Mapping, not called directly -->
   <servlet-mapping>
   <servlet-name>faces</servlet-name>
   <url-pattern>*.action</url-pattern>
</servlet-mapping>
4,修改struts.xml配置文件,加载JSF插件中定义的jsfStack拦截器栈,为了简化拦截器的配置,在struts.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>
   <!-- 将jsfFullStack拦截器栈定义成系统默认的拦截器 -->
   <default-interceptor-ref name="jsfFullStack"/>
</package>
至此,完成了JSF插件的安装,已经可以在应用中使用MyFaces页面组件了.

4, 使用JSF插件
4.1, 实现业务逻辑组件

这里展示一个JEE应用,有单独的业务逻辑组件,业务逻辑组件通过Spring容器来创建,管理.业务逻辑组件的代如下:
package lee.service;

import java.util.*;
import lee.model.Book;
public class BookService
{
private Set<Book> bookDb;
public BookService()
{
   bookDb = new HashSet<Book>();
   bookDb.add(new Book(1 , "Spring2.0宝典" , "全面介绍了Spring各个知识点"));
   bookDb.add(new Book(2 , "轻量级J2EE企业应用实战" , "介绍实际企业的J2EE开发过程"));
}

public Set<Book> getAllBook()
{
   return bookDb;
}

public Book getBookById(int id)
{
   for (Book b : bookDb)
   {
    if (b.getId() == id)
    {
     return b;
    }
   }
   return null;
}


public void addBook(Book b)
{
   bookDb.add(b);
}
}
实现了上面的业务逻辑组件后,必须将业务逻辑组件配置在Spring容器中,在Spring容器中部署业务逻辑组件的配置如下:
<?xml version="1.0" encoding="GBK"?>
<!-- 指定Spring配置文件的Schema信息 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bs" class="lee.service.BookService"/>
</beans>
因为上面的Spring容器中没有配置Action实例,我们将会通过自动装配的方式将该业务逻辑组件注入Action实例.

为了在Struts2应用中使用Spring框架,所以我们还应该在应用中安装Spring插件,将Struts2框架的lib路径下的 struts2-spring-plugin-2.0.11.2.jar文件复制到Web应用的WEB-INF\lib\路径下,还必须将 spring.jar文件也复制到Web应用的WEB-INF\lib\路径下,此外还应该在web.xml文件中配置当应用启动时自动加载Spring 容器.下面是此应用的web.xml文件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="jsf" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<!-- 定义Struts 2的核心过滤器 -->
    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
<!-- 定义Struts 2的核心过滤器拦截所有请求 -->
    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
<!-- 定义一个Listener,该Listener在应用启动时创建spring容器 -->
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
<!-- 定义一个Listener,该Listener在应用启动时加载MyFaces的context -->
    <listener>
        <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
    </listener>

<!-- JavaServer Faces Servlet Configuration, not used directly -->
<servlet>
   <servlet-name>faces</servlet-name>
   <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

<!-- JavaServer Faces Servlet Mapping, not called directly -->
   <servlet-mapping>
   <servlet-name>faces</servlet-name>
   <url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
至此,已经完成了本应用的业务逻辑层的实现,只剩下MVC的实现了.

4.2,MVC的实现
Action中的代码如下:
package lee.action;

import com.opensymphony.xwork2.ActionSupport;
import java.util.*;
import lee.model.Book;
import lee.service.BookService;
public class BookAction extends ActionSupport
{
private Book currentBook;
private int editId;

private BookService bs;
public void setBs(BookService bs)
{
   this.bs = bs;
}

public void setCurrentBook(Book currentBook)
{
   this.currentBook = currentBook;
}
public Book getCurrentBook()
{
   //如果editId请求参数不为空,则currentBook也不为空
   if (editId != 0)
   {
    this.currentBook = bs.getBookById(editId);
   }
   else if (currentBook == null)
   {
    currentBook = new Book();
   }
   return this.currentBook;
}

public void setEditId(int editId)
{
   this.editId = editId;
}
public int getEditId()
{
   return this.editId;
}

public List<Book> getAllBook()
{
   List<Book> result = new ArrayList<Book>();
   for (Book b : bs.getAllBook())
   {
    result.add(b);
   }
   return result;
}

public String save()
{
   bs.addBook(currentBook);
   return "list";
}
}
定义了上面的Action之后,还必须在struts.xml文件中配置该Action,配置的片段如下:
<package name="lee" extends="jsf">
   <action name="list" class="lee.action.BookAction">
    <result name="success" type="jsf"/>
   </action>
   <action name="edit" class="lee.action.BookAction">
    <result name="success" type="jsf"/>
    <result name="list" type="redirect">list.action</result>
   </action>
</package>
这里的list Action下的success逻辑视图对应一个类型为jsf的Result,该Result会转到list.jsp页面.

为了在list.jsp页面中列出所有的Book实例,我们使用JSF的<h:dataTable ...>页面组件,当然<h:dataTable ../>组件不可单独使用,它通常和<h:column .../>组件一起使用,下面是list.jsp页面代码:
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
<html>
<head>
   <title>Struts2+MyFaces+Spring整合</title>
</head>
<body>
<f:view>
<h3>Struts2+MyFaces+Spring整合</h3>
<h3>列出所有图书</h3>
<h:dataTable value="#{action.allBook}" var="b" style="text-align:center;width:500px" border="1">
   <h:column>
    <f:facet name="header">
     <h:outputText value="图书ID" />
    </f:facet>
    <h:outputLink value="edit.action">
     <f:param name="editId" value="#{b.id}" />
     <h:outputText value="#{b.id}" />
    </h:outputLink>
   </h:column>
   <h:column>
    <f:facet name="header">
     <h:outputText value="图书名" />
    </f:facet>
    <h:outputText value="#{b.name}" />
   </h:column>
   <h:column>
    <f:facet name="header">
     <h:outputText value="图书简介" />
    </f:facet>
    <h:outputText value="#{b.desc}" />
   </h:column>
</h:dataTable>
<p>
<h:outputLink value="edit.action">
   <h:outputText value="新增图书"/>
</h:outputLink>
</p>
</f:view>
</body>
</html>
从上面的页面文件中可以看出,上面的页面大量使用了MyFaces的页面组件,为访问Action实例的属性,MyFaces组件允许通过action引用到该页面对应的Action.例如,要访问该页面对应Action里的allBook属性,通过如下代码片段即可:
#{action.allBook} //这相当于获得Action实例的getAllBook()方法的返回值

在浏览器中直接向list.action发送请求,将可以看到列表页面的展示.可以看出,通过使用MyFaces的dataTable页面组件,可以多么方便地实现集合数据的列表显示.使用MyFaces页面组件后,还可以简化页面显示效果的控制,并可模拟JSF的MVC模式.

5, 在JSF中使用JSP标签

为了在FreeMarker模板中使用JSP标签,必须在web.xml文件中启动JSPSupportServlet,即在web.xml方便中增加如下配置:

<servlet>
   <servlet-name>JspSupportServlet</servlet-name>
   <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

然后,就可以在JSF模板中使用如下方式来导入标签库:

<#assign page=JspTaglibs["/WEB-INF/sitemesh-page.tld"]>

页面使用JSP标签的用法如下:

<@page.applyDecorator page="/link.html" name="panel" />

6, 整合JSF的思考

通过前面介绍的示例,可以看到将JSF和Struts2整合的全过程,一旦通过JSF插件整合了MyFaces框架,就可以在普通JSP页面中使用 MyFaces页面组件了,并可以以MyFaces的MVC模型实现JEE系统.整合MyFaces框架存在如下优势:
1,允许在普通的Struts2页面上使用JSF页面组件.
2,完全可以使用Struts2的配置文件,无需使用JSF配置文件.
3,保留了MyFaces框架的特征,甚至可以在Struts2页面中使用MyFaces的复杂组件.

我们通过上面的例子,并没有看到MyFaces组件有更大的特性,实际上,Struts2整合了Dojo框架之后,提供了大量的页面组件,包括 FishEye效果,富文本编辑器,各种统计图表等,Struts2去借助于MyFaces页面组件效果是否有很大的必要呢?当然,MyFaces的页面组件包含了比Dojo的组件更多的功能,就是支持后台Bean绑定,可以直接将MyFaces页面组件与Struts2的Action进行绑定,这是一种模拟桌面应用的开发方式,其实Struts2已经提供了足够的功能去支持我们的Web应用,大多数情况下都不需要再与JSF整合,但是能过这篇文章,我们可以看到Struts2提供的优秀的整合其它框架的能力.
分享到:
评论

相关推荐

    Struts2整合JSF

    《Struts 2权威指南--基于WebWork核心的MVC开发》李纲著,是学习Struts 2不错的书籍,这里给出光盘中带包源代码。所有例子直接放入tomcat下都能运行.

    JSF技术框架整合JSF代码

    就像Struts框架一样,JSF定义了一套JSF标签,能够生成与JavaBean属性绑定在一起的HTML表单元素。从应用开发者的角度看,两种框架十分相似,但是JSF可能会得到更多的支持,因为JSF是Java的标准。在未来的发展中,有...

    [Struts 2权威指南--基于WebWork核心的MVC开发(高清完整版) 1/12

    第10章 Struts 2的标签库,第11章 Struts 2的Ajax支持,第12章 使用FreeMarker充当表现层,第13章 整合Spring,第14章 整合JSF,第15章 整合SiteMesh,第16章 整合JasperReports,第17章 整合JFreeChart,第18章 ...

    struts2入门及提高

    Struts2的拦截器 Struts2整合JSF Struts2整合Ajax Struts2的国际化(Internationalization) Struts2标签库 Struts2整合Hibernate及Spring

    Struts+JSF+filter+Myfaces+A4j+Spring+hibernate+Mysql整合一个项目

    Struts+JSF+filter+Myfaces+A4j+Spring+hibernate+Mysql整合一个项目

    Struts2入门与配置

    讲解Struts2配置核心概念及原理、整合JSF、整合Ajax

    Struts2权威指南

    mvc思想,webwork 和struts2 ,拦截器,配置文件,strtus2的国际化,标签库,对ajax的支持,整合spring,整合jsf,整合hibernate, 最后一个注册登录系统,和电子拍卖系统。

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    第二部分详细讲解了jsf ri、jta、jndi、rmi、jms、javamail、ejb 3的session bean、message driven bean、jpa、jax-ws 2、jaas等java ee知识,这部分知识以jsf+ejb 3+jpa整合开发为重点,通过使用netbeans ide工具...

    国际化和拦截器还有标签库

    大家下载下来之后 ,照着里面的代码写下去就行了。里面的内容包括了以下: ...Struts2整合JSF Struts2整合Ajax Struts2的国际化(Internationalization) Struts2标签库 Struts2整合Hibernate及Spring

    Struts2+Hibernate+Spring框架电子商城

    本系统采用的关键技术是Struts2+Hibernate+Spring整合和AJAX。之所以采用SSH整合是因为在软件工程领域,为了降低模块耦合度,提高模块的可重用性,分层一直是广为采纳的一个方法。其实分层还可以使开发人员专注于某...

    struts2+spring2.5+hibernate3.1整合包

    该整合包是我做的视频系统,资源管理系统,及考场系统项目中lib里打包出来的,应用中还有别的包我给选出来了,由于整个整合包太大,我只抽取了ssh2的相关包打包发布了,如果有别的应用整合包的需求可以联系我。...

    Struts2权威指南完整版

    这是李刚写的Struts2权威指南完整版,讲解得比较详细,还介绍与spring、jsf、hibernate等的整合和相应的实例。

    struts 入门ppt

    struts2 入门 经过七年多的发展,Struts1已经成为了一个高度成熟的框架,不管是稳定性还是可靠性都 得到了广泛的证明。但是随着时间的流逝,技术的进步,Struts1的局限性也越来越多地暴 露出来,并且制约了Struts1的...

    JAVA WEB典型模块与项目实战大全.zip

    以Java EE主流框架整合应用及项目开发为主线,通过Java Web开发中最常见的19个典型模块和5个完整的项目案例,详细介绍了Struts 2.x、Spring、Guice、Hibernate、iBATIS、JPA、JSF和AJAX等热门开源技术及JSP +Java ...

    JAVA WEB典型模块与项目实战大全

    以Java EE主流框架整合应用及项目开发为主线,通过Java Web开发中最常见的19个典型模块和5个完整的项目案例,详细介绍了Struts 2.x、Spring、Guice、Hibernate、iBATIS、JPA、JSF和AJAX等热门开源技术及JSP +Java ...

    Java.Web典型模块与项目实战大全

    以Java EE主流框架整合应用及项目开发为主线,通过Java Web开发中最常见的19个典型模块和5个完整的项目案例,详细介绍了Struts 2.x、Spring、Guice、Hibernate、iBATIS、JPA、JSF和AJAX等热门开源技术及JSP +Java ...

    JavaEE5学习笔记13-JSF集成Facelets使用经验总结

    JavaEE5学习笔记13-JSF集成Facelets使用经验总结.

    SSH相关整合的总要资料

    它提供了对ORM工具(Hibernate,JDO,TopLink,apacheOJB,iBatis,JPA)、视图(JSP,JSTL,Title,Velocity,FreeMarker,XSLT,PDF/Excel文档视图、JasperReports报表视图)、Web框架(JSF、Struts、Tapestry、WebWork)其他技术...

    JAVA程序开发大全---上半部分

    本书系统全面地介绍了Java中的各项主流技术,以及基于这些技术的商业化应用程序的开发技巧,在讲解过程中以目前最为流行的开发工具MyEclipse为载体,全面系统地介绍了如何在MyEclipse中开发基于Struts、Hibernate、...

    Java Web开发从初学到精通随书光盘源码

    《Java Web开发从初学到精通》开始主要介绍Servlet、JSP、JavaBean、EL、JSTL、JDBC等Web开发基础知识,然后学习Struts、Hibernate、Spring、Ajax、JSF等开源框架,并最终学习如何整合这些开源框架进行J2EE开发,...

Global site tag (gtag.js) - Google Analytics