首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

运用JSF开发:视图(一)

2012-10-20 
使用JSF开发:视图(一)一.MVC几乎是Java Web framework的结构总纲,不过纷乱的框架各有巧妙,实现各有不同。一

使用JSF开发:视图(一)
      
一.MVC几乎是Java Web framework的结构总纲,不过纷乱的框架各有巧妙,实现各有不同。  一.Struts、Webwork、Spring MVC      
   基于C/S模式的设计结构,不隐藏基于请求/响应通讯协议内容的思维模式,早期的Web开发者,都已经习惯这样思考,学习曲线比较平滑,比较容易入门,而且Struts从诞生至今,抢占了不少市场,有大量的用户群。现在Struts和Webwork双剑合璧衍生出的Struts2是这种结构的最强代表,在普遍的企业系统中都可以胜任,是开发不错的选择。

   (1).Tapestry、Wicket、JSF      
   基于组件的设计结构,亮点在于转变Web应用开发的思维模式,不能说新颖,但是很具特色,也已经被开发人员所接受,Tapestry诞生的比较早,在非官方的市场风光无限,个人也非常喜欢,但是3.0和4.x版本中都有一些令人不太愉快的地方,5.0目前还没有发布正式版本(莫非要等到零八奥运。。。)。三者之中Wicket的入门最快,学习曲线最低,而且笔者提供的组件相当丰富,是一个非常优秀的轻量级框架,一些比较小的企业系统中,强烈推荐使用。

   (2).Other       
   还有一些其他的框架,如Echo2,Conoon,Shale,Tuibine等等,这些产品中有的自成体系,有的是其他产品的补充,虽然各有亮点,但是很难撼动前面两者的地位了。

   (3).郁闷的JSF       
  同样的设计结构,Tapesty和Wicket诞生就伴随着很多的赞美,可是JSF却冷落了很多,批评和泼冷水的人居然占大多数(难道JSF是后妈生的…)。所有的JSR定义,实现由厂商来玩,基于接口编程的思维,定义与实现分离,这是不错的拆分解藕的设计,可是由于JSF定义本身不够完善合理,厂商初期的不太买账,开源的实现又不够稳定放心等等原因,果然导致JSF一片骂声。JSF真的有这么差,偶倒是觉得,见仁见智!

   二.视图       
  JSF说到底MVC结构,我们就先来解决诟病最多的视图(View)层。JSF的缺省视图技术是JSP(不可能要求SUN自抽耳光,抛弃JSP是不可能滴),也是大家骂声最多的,诸如Taglib是失败的技术,不能所见即所得可视化编辑,缺少优秀的IDE支持,代码侵入严重,程序和美工不能良好分离。

View之一JSP
        JSP作为J2EE中标准的视图技术,是相当稳定和强悍的。Taglib并不是一项失败的技术,不过它的确是一项学习曲线比较高的技术,在稳定的团队中有良好的表现,但是在流水的阵营中,学习和维护的成本可能真的是不太能接受的。
        关于JSP和Taglib的指南,几乎使用Java开发Web应用的人都有涉猎,而且互联网上的教程例子一陀一陀的,就不说了。
        引用一句老兄的话,无论多么优秀的语言,都可以写出糟糕的代码。JSP+Taglib是一项成熟和稳定技术,代码一样可以写的很优雅,不过对程序员和美工的要求都稍微都高了一点(#>.<)。

View之二Facelets
        Facelets模板框架是目前JSF优秀的视图解决技术,基于标准的XML技术,让JSF的开发效率有了很大的提升。
模板
      使用Facelets的具体步骤
1.下载Facelets的最新发行包
2.引入jsf-facelets.jar到项目依赖库
3.配置web.xml文件 <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>

4.配置faces-config.xml文件 <application>   
        <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>

  到此为止,Facelets的准备工作已经OK,正式开工!
  index.xhtml 代码
  步骤一:创建布局页面 template.xhtml
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title><ui:insert name="title">Default Title</ui:insert>
        </title>
     <style type="text/css">
           body {
            font-family: Verdana, Arial, Helvetica, sans-serif;
            font-size: small;
            }
    </style>
    </head>
    <body>
        <div id="head">
            <ui:insert name="head">Default Head</ui:insert>
        </div>
        <hr />
        <div id="header">
            <ui:insert name="body">Default Body</ui:insert>
        </div>
        <hr />
        <div id="header">
            <ui:insert name="foot">Default Foot!</ui:insert>
        </div>
    </body>
</html>

         
    步骤二:使用布局模板index.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:d="http://demo.phoenixup.org/jsf">  
    <ui:composition template="/WEB-INF/template/template.xhtml">
        <ui:define name="title">
            This is a demo application!   
          </ui:define>
        <ui:define name="head">
            <div id="head">
                <h2>
                    This is HEAD!
                </h2>
            </div>
        </ui:define>
        <ui:define name="body">
            【略】
        </ui:define>
        <ui:define name="foot">
            <div id="foot">
                <h2>
                    This is FOOT!
                </h2>
            </div>
        </ui:define>
    </ui:composition>
</html>

标签内容

?ui:insert 标记定义逻辑区域
?ui:composition调用模板
?ui:define 填充区域内容
具体的标签的教程可以参考Facelets的官方文档,使用很简单。

使用JSFC
        jsfc的灵感来自Tapestry,使用转义标签,可以在不破坏页面的可视编辑的前提的下,优雅的解决了程序与视图分离,代码侵入的问题,令程序员和美工都很Happy。

组件
        使用厂商组件
        Facelets与使用已完场的组件是非常容易的,以tomahawk为例

  1.创建 Facelets 标记文件(/WEB-INF/taglibs/ tomahawk.taglib.xml文件)
  2.在 web.xml 中声明标记库
<context-param>
        <param-name>facelets.LIBRARIES</param-name>
        <param-value>
            /WEB-INF/taglibs/tomahawk.taglib.xml
        </param-value>
</context-param>
<!--引入多个文件以分号(;)分割 -->

  3.用命名空间导入标记文件。
  index.xhtml 代码

1.<html xmlns="http://www.w3.org/1999/xhtml" 
2.    xmlns:ui="http://java.sun.com/jsf/facelets" 
3.    xmlns:h="http://java.sun.com/jsf/html" 
4.    xmlns:t="http://myfaces.apache.org/tomahawk"

5.    xmlns:d="http://demo.phoenixup.org/jsf"> 
   4.使用组件
    index.xhtml 代码

1.<input type="text" id="startDate" jsfc="t:inputCalendar"  
2.value="#{helloworld.start}" renderAsPopup="true" 
3.popupDateFormat="yyyy-MM-dd" renderPopupButtonAsImage="true" required="true" /> 

开发JSF组件       
   说真的JSF的组件开发,并不是一件很容易的事情,但是也绝不困难,下面就是一个最经典和老土的HelloWorld的例子,这个组件例子在JSF1.2定义的基础上开发,在JSF  RI1.2.04和MyFaces1.20中都能良好运行,如果有兴趣的可以看看Sun的官方文档,还有参照一下Myfaces1.20的实现。

JSF的组件生命周期,图详参考:
http://www.iteye.com/topic/123728

这个图是从请求至响应中组件解码与编码,调用,渲染,等等一系列的动作过程。有了对JSF生命周期的理解,组件的开发就很清晰了。
        1.创建Component          
       LabelComponent.java代码
1.package demo; 
2. 
3.import java.io.IOException; 
4. 
5.import javax.faces.component.UIOutput; 
6.import javax.faces.context.FacesContext; 
7.import javax.faces.context.ResponseWriter; 
8. 
9.public class LabelComponent extends UIOutput { 
10.    @Override 
11.    public String getFamily() { 
12.        return "demo.component.Label"; 
13.    } 
14. 
15.    @Override 
16.    public String getRendererType() { 
17.        return "demo.renderer.Label"; 
18.    } 
19.} 
         
        只覆盖了两个方法,确定了组件和渲染器的关键字。

        2.创建Renderer      
     LabelRenderer.java 代码
1.package demo; 
2. 
3.import java.io.IOException; 
4. 
5.import javax.faces.component.UIComponent; 
6.import javax.faces.component.UIInput; 
7.import javax.faces.component.UIOutput; 
8.import javax.faces.context.FacesContext; 
9.import javax.faces.context.ResponseWriter; 
10.import javax.faces.render.Renderer; 
11. 
12.public class LabelRenderer extends Renderer { 
13. 
14.    @Override 
15.    public void encodeBegin(FacesContext context, UIComponent component) 
16.            throws IOException { 
17.        FacesContext.getCurrentInstance().getExternalContext().log("Start."); 
18.        ResponseWriter writer = context.getResponseWriter(); 
19.        UIOutput ui = (UIOutput) component; 
20.         
21.        writer.startElement("label", component); 
22.        Object style = ui.getAttributes().get("style"); 
23.        if (null != style) 
24.            writer.writeAttribute("style", style.toString(), null); 
25.        Object value = ui.getAttributes().get("value"); 
26.        if (null != value) 
27.            writer.write(value.toString()); 
28.        writer.endElement("label"); 
29.        writer.flush(); 
30.    } 
31. 
32.    @Override 
33.    public void encodeEnd(FacesContext context, UIComponent component) 
34.            throws IOException { 
35.        FacesContext.getCurrentInstance().getExternalContext().log("The end."); 
36.    } 
37.} 

        具体的内容实现。
        3.创建Taglib     
       LabelTag.java 代码

1.package demo; 
2. 
3.import javax.el.ValueExpression; 
4.import javax.faces.component.UIComponent; 
5.import javax.faces.webapp.UIComponentELTag; 
6. 
7.public class LabelTag extends UIComponentELTag { 
8. 
9.    private ValueExpression value; 
10.    private ValueExpression style; 
11. 
12.    public void setValue(ValueExpression value) { 
13.        this.value = value; 
14.    } 
15. 
16.    public void setStyle(ValueExpression style) { 
17.        this.style = style; 
18.    } 
19. 
20.    @Override 
21.    protected void setProperties(UIComponent component) { 
22.        if(component ==null || !(component instanceof LabelComponent)) 
23.            throw new IllegalArgumentException("Component is not deom.component.LabelComponent"); 
24.        LabelComponent comp=(LabelComponent)component; 
25.        super.setProperties(component); 
26.        if(value!=null) 
27.            comp.setValueExpression("value", value); 
28.        if(style!=null) 
29.            comp.setValueExpression("style", style); 
30.         
31.    } 
32. 
33.    @Override 
34.    public String getComponentType() { 
35.        return "demo.component.Label"; 
36.    } 
37. 
38.    @Override 
39.    public String getRendererType() { 
40.        return "demo.renderer.Label"; 
41.    } 
42. 
43.} 

        继承UIComponentELTag,指定组件和渲染器。      

        demo.tld 代码

1.xml version="1.0" encoding="UTF-8"?> 
2.1.    PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"  
2.    "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd" > 
3.<taglib> 
4.    <tlib-version>1.0tlib-version> 
5.    <jsp-version>2.0jsp-version> 
6.    <short-name>demoshort-name> 
7.    <uri>http://demo.phoenixup.org/jsfuri> 
8.    <tag> 
9.        <name>labelname> 
10.        <tag-class>demo.LabelTagtag-class> 
11.        <attribute> 
12.            <name>valuename> 
13.            <required>truerequired> 
14.        attribute> 
15.        <attribute> 
16.            <name>stylename> 
17.        attribute> 
18.    tag> 
19.taglib> 

        4.编辑faces-config.xml、配置Facelets
        faces-config.xml 代码

1.<component> 
2.    <component-type>demo.component.Labelcomponent-type> 
3.    <component-class>demo.LabelComponentcomponent-class> 
4.component> 
5.<render-kit> 
6.    <renderer> 
7.        <component-family>demo.component.Labelcomponent-family> 
8.        <renderer-type>demo.renderer.Labelrenderer-type> 
9.        <renderer-class>demo.LabelRendererrenderer-class> 
10.    renderer> 
11.render-kit> 
demo.taglib.xml 代码

1.<tag> 
2.    <tag-name>labeltag-name> 
3.    <component> 
4.        <component-type>demo.component.Labelcomponent-type> 
5.        <renderer-type>demo.renderer.Labelrenderer-type> 
6.    component> 
7.tag> 

        5.使用
         index.xhtml 代码

1.<html xmlns="http://www.w3.org/1999/xhtml" 
2.    xmlns:ui="http://java.sun.com/jsf/facelets" 
3.    xmlns:h="http://java.sun.com/jsf/html" 
4.    xmlns:t="http://myfaces.apache.org/tomahawk" 
5.    xmlns:d="http://demo.phoenixup.org/jsf"> 
6. 
7.    <label jsfc="d:label" value="#{helloworld.title}" style="color: red; size: 12" /> 

        组件只是简单的接受两个参数value和style,作为显示的内容,和显示格式。

复合组件
        Facelets还有一种复合组件的功能,下面这个例子有个演示
        1.创建复合组件
        calendar.xhtml 代码

1.<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" 
2.    xmlns:ui="http://java.sun.com/jsf/facelets" 
3.    xmlns:h="http://java.sun.com/jsf/html" 
4.    xmlns:t="http://myfaces.apache.org/tomahawk"> 
5.    <ui:composition>     
6.        <input type="text" jsfc="t:inputCalendar" id="${id}" 
7.                        value="${backingbean}" renderAsPopup="true" 
8.                        popupDateFormat="${dateformat}" renderPopupButtonAsImage="true" 
9.                        required="true" /> 
10.    ui:composition> 
11.html> 
  
        2.定义复合组件
<tag>
        <tag-name>calendar</tag-name>
        <source>source/calendar.xhtml</source>
</tag>

  原文地址:http://www.iteye.com/topic/123728.

热点排行
Bad Request.