Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6645274
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: Java

2007-09-16 16:51:46

JSF入门 [转贴 2006-11-21 11:34:27 ] 发表者: tianying_fly   
字体变小 字体变大

文章来源:

 

如果您是从使用的角度来看JSF,则您不用理会HTTP、数据转换等细节,JSF将细节都隐藏起来了,无论您是网页设计人员或是应用程序设计人员,都可以使用自己熟悉的方式来看JSF

1. 入门

借由以下的几个主题,可以大致了解JSF的轮廓与特性,我们来看看网页设计人员与应用程序设计人员各负责什么。

1.1 简介JSF

Web应用程序的开发与传统的单机程序开发在本质上存在着太多的差异,Web应用程序开发人员至今不可避免的必须处理HTTP的细节,而HTTP无状态的(stateless)本质,与传统应用程序必须维持程序运行过程中的信息有明显的违背,再则Web应用程序面对网站上不同的使用者同时的存取,其执行线程安全问题以及数据验证、转换处理等问题,又是复杂且难以解决的。

另一方面,本质上是静态的HTML与本质上是动态的应用程序又是一项违背,这造成不可避免的,处理网页设计的美术人员与程序设计人员,必须被彼此加入至视图组件中的逻辑互相干扰,即便一些视图呈现逻辑以标签的方式呈现,试图展现对网页设计美术人员的亲切,但它终究必须牵涉到相关的流程逻辑。

有很多方案试着解决种种的困境,而各自的着眼点各不相同,有的从程序设计人员的角度来解决,有的从网页设计人员的角度来解决,各种的框架被提出,所造成的是各种不统一的标签与框架,为了促进产能的集成开发环境(IDE)难以整合这些标签与框架,另一方面,开发人员的学习负担也不断的加重,他们必须一人了解多个角色的工作。

JavaServer Faces的提出在试图解决这个问题,它试图在不同的角度上提供网页设计人员、应用程序设计人员、组件开发人员解决方案,让不同技术的人员可以彼此合作又不互相干扰,它综合了各家厂商现有的技术特点,由Java Community ProcessJCP)团队研拟出来的一套标准,并在2004年三月发表了JavaServer Faces 1.0实现成果。

从网页设计人员的角度来看,JavaServer Faces提供了一套像是新版本的HTML标签,但它不是静态的,而是动态的,可以与后端的动态程序结合,但网页设计人员不需要理会后端的动态部份,网页设计人员甚至不太需要接触JSTL这类的标签,也可以动态的展现数据(像是动态的查询表格内容),JavaServer Faces提供标准的标签,这可以与网页编辑程序结合在一起,另一方面,JavaServer Faces也允许您自定义标签。

从应用程序设计人员的角度来看,JavaServer Faces提供一个与传统应用程序开发相类似的模型(当然因某些本质上的差异,模型还是稍有不同),他们可以基于事件驱动来开发程序,不必关切HTTP的处理细节,如果必须处理一些视觉组件的属性的话,他们也可以直接在整合开发环境上拖拉这些组件,点选设定组件的属性,JavaServer Faces甚至还为应用程序设计人员处理了对象与字符串(HTTP传送本质上就是字符串)间不匹配的转换问题。


2 页 共 55 JSF 入门

UI组件开发人员的角度来看,他们可以设计通用的UI组件,让应用程序的开发产能提高,就如同在设计Swing组件等,UI开发人员可以独立开发,只要定义好相关的属性选项来调整细节,而不用受到网页设计人员或应用程序设计人员的干扰。

三个角色的知识领域原则上可以互不干扰,根据您的角色,您只要了解其中一个知识领域,就可以运用JavaServer Faces,其它角色的知识领域您可以不用了解太多细节。

当然,就其中一个角色单独来看,JavaServer Faces隐藏了许多细节,若要全盘了解,其实JavaServer Faces是复杂的,每一个处理的环境都值得深入探讨,所以学习JavaServer Faces时,您要选择的是通盘了解,还是从使用的角度来了解,这就决定了您学习时所要花费的心力。

要使用JSF,首先您要先取得JavaServer Faces参考实现(JavaServer Faces Reference Implementation),在将来,JSF会与Container整合在一起,届时您只要下载支持的Container,就可以使用JSF的功能。

请至 JSF 官方网站的 下载区 下载参考实现,在下载压缩文件并解压缩之后,将其 lib 目录下的 jar 文件复制至您的Web应用程序的/WEB-INF/lib目录下,另外您还需要 jstl.jar standard.jar 文件,这些文件您可以在 sample 目录下,解压缩当中的一个范例,在它的/WEB-INF/lib目录下找到,将之一并复制至您的Web应用程序的/WEB-INF/lib目录下,您总共需要以下的文件:

* jsf-impl.jar 
* jsf-api.jar 
* commons-digester.jar 
* commons-collections.jar 
* commons-beanutils.jar 
* jstl.jar 
* standard.jar 

接下来配置Web应用程序的web.xml,使用JSF时,所有的请求都通过FacesServlet来处理,您可以如下定义:

  &S226; web.xml

 

 
xmlns:xsi="" 
xsi:schemaLocation=" 
/web-app_2_4.xsd" 
version="2.4"> 
 
JSF Demo 
 
JSF Demo 
 
Faces Servlet 
 

3 页 共 55 JSF 入门

javax.faces.webapp.FacesServlet 
 
1 
 
 
Faces Servlet 
*.faces 
 
 
index.html 
 
 

在上面的定义中,我们将所有.faces的请求交由FaceServlet来处理,FaceServlet会唤起相对的.jsp网页,例如请求是/index.faces的话,则实际上会唤起/index.jsp网页,完成以上的配置,您就可以开始使用JSF了。

1.2 第一个JSF程序

现在可以开发一个简单的程序了,我们将设计一个简单的登入程序,使用者提交名称,之后由程序显示使用者名称及欢迎信息。

程序开发人员

先看看应用程序开发人员要作些什么事,我们编写一个简单的JavaBean

  &S226; UserBean.java

 

package onlyfun.caterpillar; 
public class UserBean { 
private String name; 
public void setName(String name) { 
this.name = name; 
} 
public String getName() { 
return name; 
} 
} 

这个Bean将存贮使用者的名称,编译好之后放置在/WEB-INF/classes下。

接下来设计页面流程,我们将先显示一个登入网页/pages/index.jsp,使用者填入名称并提交表单,之后在/pages/welcome.jsp中显示Bean中的使用者名称


4 页 共 55 JSF 入门

与欢迎信息。

为了让JSF知道我们所设计的Bean以及页面流程,我们定义一个/WEB-INF/faces-config.xml

  &S226; faces-config.xml

 

 
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" 
""> 
 
 
/pages/index.jsp 
 
login 
/pages/welcome.jsp 
 
 
 
user 
 
onlyfun.caterpillar.UserBean 
 
session 
 
 

中,我们定义了页面流程,当请求来自中指定的页面,并且指定了中的login时,则会将请求导向至所指定的页面。

中我们可以统一管理我们的Bean,我们设定Bean对象的存活范围是session,也就是使用者开启浏览器与程序互动过程中都存活。

接下来要告诉网页设计人员的信息是,他们可以使用的Bean名称,即中设定的名称,以及上面所定义的页面流程。

网页设计人员

首先网页设计人员编写index.jsp网页:

  &S226; index.jsp

 

<%@taglib uri="" prefix="f" %> 
<%@taglib uri="" prefix="h" %> 
<%@page contentType="text/html;charset=GB2312"%> 
 

5 页 共 55 JSF 入门

 
第一个JSF程序 
 
 
 
 

请输入您的名称

名称: 

 
 
 

 
 

我们使用了JSFcorehtml标签库,core是有关于UI组件的处理,而html则是有关于HTML的进阶标签。

有类似的作用,当您要开始使用JSF组件时,这些组件一定要在之间,就如同使用HTML时,所有的标签一定要在< /html>之间。

html标签库中几乎都是与HTML标签相关的进阶标签,会产生一个表单,我们使用来显示user这个Bean对象的name属性,而会产生一个提交按钮,我们在action属性中指定将根据之前定义的login页面流程中前往welcome.jsp页面。

网页设计人员不必理会表单传送之后要作些什么,他只要设计好欢迎页面就好了:

  &S226; welcome.jsp

 

<%@ taglib uri="" prefix="f" %> 
<%@ taglib uri="" prefix="h" %> 
<%@page contentType="text/html;charset=GB2312"%> 
 
 
第一个JSF程序 
 
 
 
 您好! 

欢迎使用 JavaServer Faces!

 
 
 

这个页面没什么需要解释的了,如您所看到的,在网页上没有程序逻辑,网页设计人员所作的就是遵照页面流程,使用相关名称取出数据,而不用担心实际上程序是如何运行的。


6 页 共 55 JSF 入门

接下来启动Container,连接上您的应用程序网址,例如:,填入名称并提交表单,您的欢迎页面就会显示了。

1.3简单的导航 Navigation

第一个JSF程序 中,我们简单的定义了页面的流程由 index.jsp welcome.jsp,接下来我们扩充程序,让它可以根据使用者输入的名称与密码是否正确,决定要显示欢迎信息或是将使用者送回原页面进行重新登入。

首先我们修改一下UserBean

  &S226; UserBean.java

 

package onlyfun.caterpillar; 
public class UserBean { 
private String name; 
private String password; 
private String errMessage; 
public void setName(String name) { 
this.name = name; 
} 
public String getName() { 
return name; 
} 
public void setPassword(String password) { 
this.password = password; 
} 
public String getPassword() { 
return password; 
} 
public void setErrMessage(String errMessage) { 
this.errMessage = errMessage; 
} 
public String getErrMessage() { 
return errMessage; 
} 

7 页 共 55 JSF 入门

public String verify() { 
if(!name.equals("justin") || 
!password.equals("123456")) { 
errMessage = "名称或密码错误"; 
return "failure"; 
} 
else { 
return "success"; 
} 
} 
} 

UserBean中,我们增加了密码与错误信息属性,在verify()方法中,我们检查使用者名称与密码,它传回一个字符串,"failure"表示登入错误,并会设定错误信息,而"success"表示登入正确,这个传回的字符串将决定页面的流程。

接下来我们修改一下 faces-config.xml 中的页面流程定义:

  &S226; faces-config.xml

 

 
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" 
""> 
 
 
/pages/index.jsp 
 
success 
/pages/welcome.jsp 
 
 
failure 
/pages/index.jsp 
 
 
 
user 
 
onlyfun.caterpillar.UserBean 
 
session 
 
 

8 页 共 55 JSF 入门

根据上面的定义,当传回的字符串是"success"时,将前往 welcome.jsp,如果是"failure"的话,将送回 index.jsp

接下来告诉网页设计人员Bean名称与相关属性,以及决定页面流程的verify名称,我们修改 index.jsp 如下:

  &S226; index.jsp

 

<%@ taglib uri="" prefix="f" %> 
<%@ taglib uri="" prefix="h" %> 
<%@page contentType="text/html;charset=GB2312"%> 
 
 
第一个JSF程序 
 
 
 
 

请输入您的名称

名称: 

密码: 

action="#{user.verify}"/> 
 
 
 
 

当要根据verify运行结果来决定页面流程时,action属性中使用 JSF Expression Language "#{user.verify}",如此JSF就知道必须根据verify传回的结果来导航页面。

可以取出指定的Bean之属性值,当使用者因验证错误而被送回原页面时,这个错误信息就可以显示在页面上。

1.4导航规则设置

JSF中是根据faces-config.xml设定,以决定在符合的条件成立时,该连结至哪一个页面,一个基本的设定如下:

.... 
 
/pages/index.jsp 
 
success 
/pages/welcome.jsp 
 

9 页 共 55 JSF 入门

 
failure 
/pages/index.jsp 
 
 
.... 

对于JSF,每一个视图(View)都有一个独特的标识(identifier),称之为View ID,在JSF中的View ID是从Web应用程序的环境相对路径开始计算,设定时都是以/作为开头,如果您请求时的路径是/pages/index.faces,则JSF会将副文件名改为/pages/index.jsp,以此作为view-id

中的是个选择性的定义,它规定了来源页面的条件,中定义各种导览条件,定义当表单结果符合的条件时,各自改导向哪一个目的页面,目的页面是在中定义。

您还可以在中加入,进一步规范表单结果必须根据哪一个动作方法(action method),当中是使用 JSF Expression Language 来设定,例如:

.... 
 
/pages/index.jsp 
 
#{user.verify} 
success 
/pages/welcome.jsp 
 
.... 
 
.... 

在导航时,预定义都是使用forward的方式,您可以在中加入一个,让JSF发出让浏览器重新导向(redirect)的header,让浏览器主动要求新网页,例如:

.... 
 
/pages/index.jsp 
 
success 
/pages/welcome.jsp 
 
 
.... 
 
.... 

您的来源网页可能是某个特定模组,例如在/admin/下的页面,您可以在中使用wildcards(通配符),也就是使用 * 字符,例如:


10 页 共 55 JSF 入门

.... 
 
/admin/* 
 
#{user.verify} 
success 
/pages/welcome.jsp 
 
.... 
 
.... 

在上面的设定中,只要来源网页是从/admin来的,都可以开始测试接下来的

如果没有设定,表示来源网页不作限制,您也可以使用 * 显式的在定义文件中表明,例如:

.... 
 
/* 
 
.... 
 
.... 

或者是这样:

.... 
 
* 
 
.... 
 
.... 

1.5 JSF Expression Language

JSF Expression Language 搭配 JSF 标签来使用,是用来存取数据对象的一个简易语言。

JSF EL是以#开始,将变量或运算式放置在 { } 之间,例如:

#{someBeanName} 

变量名称可以是faces-config.xml中定义的名称,如果是Bean的话,可以通过使用 '.' 运算符来存取它的属性,例如:

... 
 
 
 
... 

11 页 共 55 JSF 入门

JSF标签的属性上," " (或'')之间如果含有EL,则会加以运算,您也可以这么使用它:

... 
 
名称, 年龄:
value="#{userBean.name}, #{userBean.age}"/> 
 
... 

一个执行的结果可能是这样显示的:

名称, 年龄:Justin, 29

EL的变量名也可以程序执行过程中所声明的名称,或是JSF EL预定义的隐含对象,例如下面的程序使用param隐含对象来取得使用者输入的参数:

<%@ taglib uri="" prefix="f" %> 
<%@ taglib uri="" prefix="h" %> 
<%@page contentType="text/html; charset=GB2312"%> 
 
 
 
 
 
 
 您好,   
 
 
 

paramJSF EL预定义的隐含对象变量,它代表request所有参数的集合,实际是一个java.util.Map类型对象,JSF所提供的隐含对象,大致上对应于JSP隐含对象,不过JSF隐含对象移除了pageScopepageContext,而增加了facesContextview,它们分别对应于 javax.faces.context.FacesContextjavax.faces.component.UIViewRoot

对于Map类型对象,我们可以使用 '.' 运算符指定key值来取出对应的value,也可以使用 [ ] 来指定,例如:

... 
 
 您好,   
 
... 

[ ] 之间,也可以放置其它的变量值,例如:

... 
 
 
 

12 页 共 55 JSF 入门

... 

如果变量是List类型或阵列的话,则可以在 [] 中指定索引,例如:

.... 
 
 
 
value="#{someBean.someListOrArray[user.age]}"/> 
 
.... 

您也可以指定字面常数,对于truefalse、字符串、数字,JSF EL会尝试进行转换,例如:

.... 
 
.... 
 
.... 

如果要输出字符串,必须以单引号 ' 或双引号 " 括住,如此才不会被认为是变量名称。

在声明变量名称时,要留意不可与JSF的保留字或关键字同名,例如不可取以下这些名称:

true false null div mod and or not eq ne lt gt le ge instanceof empty

使用EL,您可以直接实行一些算术运算、逻辑运算与关系运算,其使用就如同在一般常见的程序语言中之运算。

算术运算符有:加法 (+), 减法 (-), 乘法 (*), 除法 (/ or div) 与余除 (% or mod) 。下面是算术运算的一些例子:

运算式

结果

#{1}

1

#{1 + 2}

3

#{1.2 + 2.3}

3.5

#{1.2E4 + 1.4}

12001.4

#{-4 - 2}

-6

#{21 * 2}

42

#{3/4}

0.75

#{3 div 4}

0.75,除法

 


13 页 共 55 JSF 入门

#{3/0}

Infinity

#{10%4}

2

#{10 mod 4}

2,也是余除

#{(1==2) ? 3 : 4}

4

 

如同在Java语法一样 ( expression ? result1 : result2)是个三元运算,expressiontrue显示result1false显示result2

逻辑运算有:and(&&)or(!!)not(!)。一些例子为:

运算式

结果

#{true and false}

false

#{true or false}

true

#{not true}

false

 

关系运算有:小于Less-than (< or lt)、大于Greater-than (> or gt)、小于或等于Less-than-or-equal (<= or le)、大于或等于Greater-than-or-equal (>= or ge)、等于Equal (== or eq)、不等于Not Equal (!= or ne),由英文名称可以得到ltgt等运算符之缩写词,以下是Tomcat的一些例子:

运算式

结果

#{1 < 2}

true

#{1 lt 2}

true

#{1 > (4/2)}

false

#{1 > (4/2)}

false

#{4.0 >= 3}

true

#{4.0 ge 3}

true

#{4 <= 3}

false

#{4 le 3}

false

#{100.0 == 100}

true

#{100.0 eq 100}

true

#{(10*10) != 100}

false

#{(10*10) ne 100}

false

 


14 页 共 55 JSF 入门

左边是运算符的使用方式,右边的是运算结果,关系运算也可以用来比较字符或字符串,按字典顺序来决定比较结果,例如:

运算式

结果

#{'a' < 'b'}

true

#{'hip' > 'hit'}

false

#{'4' > 3}

true

 

EL运算符的执行优先顺序与Java运算符对应,如果有疑虑的话,也可以使用括号()来自行决定先后顺序。

1.6国际化信息

(注:本节原文是针对繁体中文进行说明的,在进行繁简转换的过程中,将原来针对繁体中文的描述全部改为简体中文了。)

JSF的国际化(Internnationalization)信息处理是基于Java对国际化的支持,您可以在一个信息资源文件中统一管理信息资源,资源文件的名称是.properties,而内容是名称与值的配对,例如:

  &S226; messages.properties

 

titleText=JSF Demo 
hintText=Please input your name and password 
nameText=name 
passText=password 
commandText=Submit 

资源文件名称由basename加上语言与地区来组成,例如:

* basename.properties 
* basename_en.properties 
* basename_zh_CN.properties 

没有指定语言与地区的basename是预定义的资源文件名称,JSF会根据浏览器送来的Accept-Language header中的内容来决定该使用哪一个资源文件名称,例如:

Accept-Language: zh_CN, en-US, en 

如果浏览器送来这些header,则预定义会使用简体中文,接着是美式英文,再来是英文语系,如果找不到对应的信息资源文件,则会使用预定义的信息资源文件。

由于信息资源文件必须是ISO-8859-1编码,所以对于非西方语系的处理,必须先将之转换为Java Unicode Escape格式,例如您可以先在信息资源文件中写下以下的内容:

  &S226; messages_zh_CN.txt

 


15 页 共 55 JSF 入门

titleText=JSF示范 
hintText=请输入名称与密码 
nameText=名称 
passText=密码 
commandText=送出 

然后使用JDK的工具程序native2ascii来转换,例如:

native2ascii -encoding GB2312 messages_zh_CN.txt messages_zh_CN.properties 

转换后的内容会如下:

titleText=JSF\u793a\u8303 
hintText=\u8bf7\u8f93\u5165\u540d\u79f0\u4e0e\u5bc6\u7801 
nameText=\u540d\u79f0 
passText=\u5bc6\u7801 
commandText=\u9001\u51fa 

接下来您可以使用标签来指定载入信息资源,一个例子如下:

  &S226; index.jsp

 

<%@ taglib uri="" prefix="f" %> 
<%@ taglib uri="" prefix="h" %> 
<%@page contentType="text/html;charset=UTF8"%> 
 
 
 
 
<h:outputText value="#{msgs.titleText}"/> 
 
 
 

: 

: 

actionListener="#{user.verify}" 
action="#{user.outcome}"/> 
 
 
 

16 页 共 55 JSF 入门

 

如此一来,如果您的浏览器预定义接受zh_CN语系的话,则页面上就可以显示中文,否则预定义将以英文显示,也就是messages.properties的内容,为了能显示多普通话系,我们设定网页编码为UTF8

可以设定locale属性,直接指定所要使用的语系,例如:

 
 

直接指定以上的话,则会使用简体中文来显示,JSF会根据basename属性加上locale属性来决定要使用哪一个信息资源文件,就上例而言,就是使用 messages_zh_CN.properties,如果设定为以下的话,就会使用messages_en.properties

 
 

您也可以在faces-config.xml中设定语系,例如:

 
 
 
en 
zh_CN 
 
 
..... 
 

一定有一个,而可以有好几个,这告诉JSF您的应用程序支持哪些语系。

当然,如果您可以提供一个选项让使用者选择自己的语系会是更好的方式,例如根据user这个Beanlocale属性来决定页面语系:

 
 

在页面中设定一个表单,可以让使用者选择语系,例如设定单选钮:

 
itemLabel="#{msgs.zh_CNText}"/> 
itemLabel="#{msgs.enText}"/> 
 

 

阅读(3473) | 评论(0) | 转发(0) |
0

上一篇:]

下一篇:Hibernate标识符生成器

给主人留下些什么吧!~~