欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

JSF 2 簡(jiǎn)介,第 1 部分: 流線化 Web 應(yīng)用程序開

系統(tǒng) 2043 0

JSF 2 簡(jiǎn)介,第 1 部分: 流線化 Web 應(yīng)用程序開發(fā)

使用 JSF 2 簡(jiǎn)化導(dǎo)航、免除 XML 配置并輕松訪問資源


級(jí)別: 中級(jí)

David Geary , 總裁, Clarity Training, Inc.

2009 年 6 月 15 日

隨著 2.0 版本的發(fā)布,Java?Server Faces (JSF) 現(xiàn)在可以輕松地實(shí)現(xiàn)健壯的、Ajax 風(fēng)格的 Web 應(yīng)用程序。本文是共三部分的系列文章的開篇,JSF 2.0 專家組成員 David Geary 將展示如何利用 JSF 2 中的新特性。在這期文章中,您將了解到如何使用 JSF 2 流線化開發(fā),您將使用注釋和約定代替 XML 配置,簡(jiǎn)化導(dǎo)航,并輕松訪問資源。并且您將看到如何在您的 JSF 應(yīng)用程序中使用 Groovy。
<!-- START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --> <!-- END RESERVED FOR FUTURE USE INCLUDE FILES-->

有關(guān) Web 應(yīng)用程序框架的最佳發(fā)源地,人們一直爭(zhēng)論不休:是象牙塔(由理論家空想而來)還是現(xiàn)實(shí)世界。在后一種情況下,框架的誕生經(jīng)受了實(shí)際需求的嚴(yán)酷考驗(yàn)。憑直覺判斷,經(jīng)受了實(shí)際需求的考驗(yàn)要?jiǎng)龠^理論家的空想,并且我認(rèn)為這種直覺完全經(jīng)得起更進(jìn)一步的檢驗(yàn)。

JSF 1 就是在象牙塔中開發(fā)的,因此,它的出現(xiàn)并沒有引起太大的轟動(dòng)。但是,JSF 做對(duì)了一件事情 — 它使市場(chǎng)上出現(xiàn)了大量來自實(shí)際開發(fā)的創(chuàng)新。早些時(shí)候,F(xiàn)acelets 的初次登場(chǎng)成為了 JavaServer Pages (JSP) 的強(qiáng)有力候補(bǔ)。然后出現(xiàn)了 Rich Faces,一個(gè)出色的 JSF Ajax 庫;接著是 ICEFaces,將 Ajax 和 JSF 聯(lián)合起來的新穎方法;還有 Seam、Spring Faces、Woodstock 組件、JSF Templating,等等。所有這些開源 JSF 項(xiàng)目都是由開發(fā)人員根據(jù)自己需要的功能構(gòu)建的。

JSF 2.0 專家組實(shí)際上對(duì)來自這些開源項(xiàng)目的最佳特性進(jìn)行了標(biāo)準(zhǔn)化。盡管 JSF 2 規(guī)范確實(shí)是由一些理論家編寫的,但它也受到了來自實(shí)際開發(fā)的創(chuàng)新的驅(qū)動(dòng)。回想起來,專家組的工作其實(shí)非常輕松,因?yàn)槲覀冋驹诰奕说募绨蛏希热?Gavin King (Seam)、Alexandr Smirnov (Rich Faces)、Ted Goddard (ICEFaces) 和 Ken Paulson (JSF Templating)。實(shí)際上,所有這些巨人都是 JSF 2 專家組的成員。因此,JSF 2 在許多方面都結(jié)合了象牙塔和真實(shí)世界的長(zhǎng)處。并且它展示了這一點(diǎn)。JSF 2 是對(duì) JSF 1 的重大改進(jìn)。

本文是共三部分的系列文章的開篇,主要有兩個(gè)目標(biāo):展示激動(dòng)人心的 JSF 2 新特性,展示如何最佳地利用這些特性,這樣您就能夠利用 JSF 2 提供的功能。通過演示 JSF 2 的應(yīng)用并伴隨一些最佳使用技巧,我將闡述前面兩個(gè)問題。下面是本文將要介紹的技巧:

  • 技巧 1:去除 XML 配置
  • 技巧 2:簡(jiǎn)化導(dǎo)航
  • 技巧 3:使用 Groovy
  • 技巧 4:利用資源處理程序

但是,我將首先介紹貫穿整個(gè)系列文章的示例應(yīng)用程序。本文的應(yīng)用程序源代碼可以 下載 獲得。

基于強(qiáng)制映射的 Web 服務(wù) mashup 示例

圖 1 展示了一個(gè) JSF mashup — 我將它稱為 places 應(yīng)用程序 — 它使用 Yahoo! Web 服務(wù)將地址轉(zhuǎn)換為地圖,并顯示縮放級(jí)別和天氣預(yù)報(bào):


圖 1. 從 Yahoo! Web Services 中查看地圖和天氣信息
從 Yahoo! Web Services 中查看地圖和天氣信息

要?jiǎng)?chuàng)建一個(gè)地點(diǎn),需要填寫地址表單,激活 Go 按鈕,然后應(yīng)用程序?qū)训刂钒l(fā)送給兩個(gè) Web 服務(wù):Yahoo! Maps 和 Yahoo! Weather。

Map 服務(wù)在 Yahoo! 服務(wù)器上返回指向地址映射的 11 個(gè)地圖 URL,使用不同的縮放級(jí)別。Weather 服務(wù)返回一些預(yù)先組裝的 HTML。圖像 URL 和 HTML 內(nèi)容都輕松地顯示在一個(gè) JSF 視圖中,這要分別感謝 <h:graphicImage> <h:outputText>

places 應(yīng)用程序使您能夠輸入任意數(shù)量的地址。您甚至可以多次使用同一個(gè)地址 ,如圖 2 所示,它實(shí)際上演示了縮放級(jí)別:


圖 2. 縮放級(jí)別
縮放級(jí)別

應(yīng)用程序的關(guān)鍵點(diǎn)

places 應(yīng)用程序有 4 個(gè)托管 bean(managed bean),如 表 1 所示:


表 1. places 應(yīng)用程序中的托管 bean
托管 bean 名稱 類 范圍
mapService com.clarity.MapService 應(yīng)用程序
weatherService com.clarity.WeatherService 應(yīng)用程序
places com.clarity.Places 會(huì)話
place com.clarity.Place 請(qǐng)求
運(yùn)行 places 應(yīng)用程序

要運(yùn)行 places 應(yīng)用程序,需要訪問 developer.yahoo.com/maps/ajax ,從 Yahoo! 獲得一個(gè)應(yīng)用程序 ID,這樣才能使用 Yahoo! Web 服務(wù)。單擊 Yahoo! Maps Web Service 中的 Get an App ID 按鈕。得到 ID 后,在 MapService.java WeatherService.java 中用您的 ID 替換 YOUR_ID_HERE

應(yīng)用程序在會(huì)話范圍內(nèi)存儲(chǔ)了一組 Place ,如 圖 1 所示,并在請(qǐng)求范圍內(nèi)維護(hù)了一個(gè) Place 。應(yīng)用程序還分別使用應(yīng)用程序范圍內(nèi)的 mapService weatherService 托管 beans 為 Yahoo! 的 map 和 weather Web 服務(wù)提供了簡(jiǎn)單的 API。

創(chuàng)建地點(diǎn)非常簡(jiǎn)單。清單 1 顯示了 圖 1 中的視圖所含的地址表單的代碼:


清單 1. 地址表單

                    
<h:form>
<h:panelGrid columns="2">
#{msgs.streetAddress} <h:inputText value="#{ place .streetAddress}" size="15"/>
#{msgs.city} <h:inputText value="#{ place .city}" size="10"/>
#{msgs.state} <h:inputText value="#{ place .state}" size="2"/>
#{msgs.zip} <h:inputText value="#{ place .zip}" size="5"/>

< h:commandButton value="#{msgs.goButtonText}"
style="font-family:Palatino;font-style:italic"
action="#{place.fetch}" />

</h:panelGrid>
</h:form>

當(dāng)用戶激活 Go 按鈕并提交表單后,JSF 將調(diào)用按鈕的操作方法: place.fetch() 。該方法將信息從 Web 服務(wù)發(fā)送到 Place.addPlace() ,后者創(chuàng)建一個(gè)新的 Place 實(shí)例,使用傳遞給方法的數(shù)據(jù)初始化實(shí)例,并將其存儲(chǔ)在請(qǐng)求范圍內(nèi)。

清單 2 展示了 Place.fetch()


清單 2. Place.fetch() 方法
                    
public class Place {
...
private String[] mapUrls
private String weather
...
public String fetch() {
FacesContext fc = FacesContext.getCurrentInstance()
ELResolver elResolver = fc.getApplication().getELResolver()

// Get maps

MapService ms = elResolver.getValue(
fc.getELContext(), null, "mapService")

mapUrls = ms.getMap(streetAddress, city, state)

// Get weather

WeatherService ws = elResolver.getValue(
fc.getELContext(), null, "weatherService")

weather = ws.getWeatherForZip(zip, true)

// Get places

Places places = elResolver.getValue(
fc.getELContext(), null, "places")

// Add new place to places

places.addPlace(streetAddress, city, state, mapUrls, weather)

return null
}
}

Place.fetch() 使用 JSF 的變量分解器(resolver)查找 mapService weatherService 托管 bean,并且使用這些托管 bean 從 Yahoo! Web 服務(wù)獲得地圖和天氣信息。隨后 fetch() 調(diào)用 places.addPlace() ,后者使用地圖和天氣信息以及地址,在請(qǐng)求范圍內(nèi)創(chuàng)建一個(gè)新的 Place

注意 fetch() 返回 null 。由于 fetch() 是一個(gè)與按鈕有關(guān)的操作方法, null 返回值使得 JSF 重新加載同一個(gè)視圖,其中顯示用戶會(huì)話中的所有位置,如清單 3 所示:


清單 3. 在視圖中顯示位置
                    
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">

<h:form>
<!-- Iterate over the list of places -->
<ui:repeat value="#{ places.placesList }" var=" place ">

<div class="placeHeading">
<h:panelGrid columns="1">

<!-- Address at the top -->
<h:panelGroup>
<div style="padding-left: 5px;">
<i><h:outputText value="#{ place.streetAddress }"/></i>,
<h:outputText value="#{ place.city }"/>
<h:outputText value="#{ place.state }"/>
<hr/>
</div>
</h:panelGroup>

<!-- zoom level prompt and drop down -->
<h:panelGrid columns="2">
<!-- prompt -->
<div style="padding-right: 10px;margin-bottom: 10px;font-size:14px">
#{msgs.zoomPrompt}
</div>

<!-- dropdown -->
<h:selectOneMenu onchange="submit() "
value="#{ place.zoomIndex }"
valueChangeListener="#{ place.zoomChanged }"
style="font-size:13px;font-family:Palatino">

<f:selectItems value="#{places.zoomLevelItems}"/>

</h:selectOneMenu>
</h:panelGrid>

<!-- The map -->
<h:graphicImage url="#{ place.mapUrl }" style="border: thin solid gray"/>

</h:panelGrid>

<!-- The weather -->
<div class="placeMap">
<div style="margin-top: 10px;width:250px;">
<h:outputText style="font-size: 12px;"
value="#{ place.weather }"
escape="false"/>
</div>
</div>
</div>

</ui:repeat>
</h:form>

</ui:composition>

清單 3 中的代碼使用 Facelets <ui:repeat> 標(biāo)記迭代用戶會(huì)話中存儲(chǔ)的位置列表。對(duì)于每個(gè)位置,輸出應(yīng)當(dāng)如圖 3 所示:


圖 3. 視圖中顯示的位置
視圖中顯示的位置

修改縮放級(jí)別

zoom 菜單(參見 圖 3 清單 3 )有一個(gè) onchange="submit()" 屬性,因此當(dāng)用戶選擇某個(gè)縮放級(jí)別時(shí),JavaScript submit() 函數(shù)提交菜單的環(huán)繞(surrounding)表單。提交表單后,JSF 調(diào)用菜單的相關(guān)值修改偵聽器 — Place.zoomChanged() 方法,如清單 4 所示:


清單 4. Place.zoomChanged()
                    
public void zoomChanged(ValueChangeEvent e) {
String value = e.getComponent().getValue()
zoomIndex = (new Integer(value)).intValue()
}

Place.zoomChanged() 在一個(gè)名為 zoomIndex Place 類的成員變量中存儲(chǔ)縮放級(jí)別。由于導(dǎo)航不會(huì)受到與服務(wù)器通信的影響,JSF 將重新加載頁面,并且地圖使用新的縮放級(jí)別進(jìn)行更新,如下所示: <h:graphicImage url=" #{place.mapUrl} ..."/> 。當(dāng)繪制地圖時(shí),JSF 調(diào)用 Place.getMapUrl() ,它返回當(dāng)前縮放級(jí)別下的地圖 URL,如清單 5 所示:


清單 5. Place.getMapUrl()
                    
public String getMapUrl() {
return mapUrls == null ? "" : mapUrls[ zoomIndex ]
}

使用少量 Facelets

如 果曾經(jīng)使用過 JSF 1,那么很可能會(huì)注意到本文的 JSF 2 代碼中存在一些細(xì)微的差別。首先,我使用了 JSF 2 的新的顯示技術(shù) — Facelets — 而不是 JSP。您將從本系列后續(xù)文章中看到,F(xiàn)acelets 提供了許多強(qiáng)大的特性來幫助您實(shí)現(xiàn)健壯、靈活和可擴(kuò)展的用戶界面。但是在前面的代碼清單中,我并沒有過多利用這種功能。然而,F(xiàn)acelets 為 JSF 帶來的眾多微小改進(jìn)之一便是能夠?qū)?JSF 值表達(dá)式直接放入到 XHTML 頁面;例如,在 清單 1 中,我將 #{msgs.city} 等表達(dá)式直接放入頁面中。如果使用 JSF 1,則必須將表達(dá)式封裝到 <h:outputText> 中,例如 <h:outputText value="#{msgs.city}"/> 。但要注意,出于安全考慮,必須始終將來自用戶輸入的文本進(jìn)行轉(zhuǎn)義,例如,在 清單 3 中我使用了 <h:outputText> ,它在默認(rèn)情況下轉(zhuǎn)義其文本來顯示位置信息。

從 Facelets 角度來講,還需要注意 清單 3 中的 <ui:composition> 標(biāo)記。該標(biāo)記指定清單 3 中的 XHTML 頁面將被包含到其他 XHTML 頁面中。Facelets composition 是 Facelets templating 的中心組件,類似于流行的 Apache Tiles 框架。在本文的后續(xù)文章中,我將討論 Facelets 模板并展示如何根據(jù) Composed Method Smalltalk 模式構(gòu)建您的視圖。

目前為止,前面的代碼并沒有使用 Facelets,與 JSF 1 相比沒有出現(xiàn)顯著的變化。現(xiàn)在,我將展示更加大的差異。第一個(gè)比較大的差異體現(xiàn)在將要為 JSF 2 應(yīng)用程序編寫的 XML 配置的數(shù)量方面。





回頁首


技巧 1:去掉 XML 配置

Web 應(yīng)用程序的 XML 配置始終是個(gè)麻煩問題 — 它非常冗長(zhǎng)并且容易出現(xiàn)錯(cuò)誤,因此最好將 XML 配置委托給一個(gè)框架,比如通過注釋、約定或特定于領(lǐng)域的語言。作為開發(fā)人員,我們應(yīng)該能夠集中精力實(shí)現(xiàn)一些操作,而不是將浪費(fèi)時(shí)間在冗長(zhǎng)的 XML 方面。

作為一個(gè)典型的例子,清單 6 展示了在使用 JSF 1 的情況下,在 places 應(yīng)用程序中聲明托管 bean 所需的 20 行 XML 代碼:


清單 6. JSF 1 的托管 bean 聲明
                    
<managed-bean>
<managed-bean-class>com.clarity.MapService</managed-bean-class>
<managed-bean-name>mapService</managed-bean-name>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>

<managed-bean>
<managed-bean-class>com.clarity.WeatherService</managed-bean-class>
<managed-bean-name>weatherService</managed-bean-name>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>

<managed-bean>
<managed-bean-class>com.clarity.Places</managed-bean-class>
<managed-bean-name>places</managed-bean-name>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
<managed-bean-class>com.clarity.Place</managed-bean-class>
<managed-bean-name>place</managed-bean-name>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

對(duì)于 JSF 2,XML 消失了,您將對(duì)類使用注釋,如清單 7 所示:


清單 7. JSF 2 的托管 bean 注釋
                    
@ManagedBean(eager=true)
public class MapService {
...
}

@ManagedBean(eager=true)
public class WeatherService {
...
}

@ManagedBean()
@SessionScoped
public class Places {
...
}

@ManagedBean()
@RequestScoped
public class Place {
...
}

按照約定,托管 bean 的名稱與類名相同,類名的第一個(gè)字母被轉(zhuǎn)換為小寫。例如, 清單 7 中創(chuàng)建的托管,從上到小依次為: mapService weatherService places place 。也可以使用 ManagedBean 注釋的 name 屬性顯式地指定一個(gè)托管 bean,比如: @ManagedBean(name = "place")

清單 7 中,我對(duì) mapService webService 托管 bean 使用 eager 屬性。當(dāng) eager 屬性為 true 時(shí),JSF 將在啟動(dòng)時(shí)創(chuàng)建托管 bean 并將其放入應(yīng)用程序范圍。

也可以使用 @ManagedProperty 注釋設(shè)置托管 bean 屬性。 表 2 展示了 JSF 2 托管 bean 注釋的完整列表:


表 2. JSF 2 托管 bean 注釋( @...Scoped 注釋只對(duì) @ManagedBean 有效)
托管 bean 注釋 描述 屬性
@ManagedBean

以托管 bean 的形式注冊(cè)一個(gè)類實(shí)例,然后將其放入到使用其中一個(gè) @...Scoped 注釋指定的范圍內(nèi)。如果沒有指定任何范圍,JSF 將把此 bean 放入請(qǐng)求范圍,如果沒有指定任何名稱,JSF 將把類名的第一個(gè)字母轉(zhuǎn)換為小寫,形成一個(gè)托管 bean 名稱;例如,如果類名為 UserBean ,那么 JSF 將創(chuàng)建一個(gè)托管 bean,其名為 userBean eager name 屬性都是可選的。

注釋必須結(jié)合使用一個(gè)實(shí)現(xiàn)零參數(shù)構(gòu)造器的 Java 類。

eager name
@ManagedProperty

為托管 bean 設(shè)置一個(gè)屬性。注釋必須放在類成員變量的聲明之前。 name 屬性指定特性的名稱,默認(rèn)情況下為成員變量的名稱。 value 屬性是特性的值,可以是一個(gè)字符串,也可以是一個(gè) JSF 表達(dá)式,比如 #{...}

value name
@ApplicationScoped 在應(yīng)用程序范圍內(nèi)存儲(chǔ)托管 bean。
@SessionScoped 在會(huì)話范圍內(nèi)存儲(chǔ)托管 bean。
@RequestScoped 在請(qǐng)求范圍內(nèi)存儲(chǔ)托管 bean。
@ViewScoped 在視圖范圍內(nèi)存儲(chǔ)托管 bean。
@NoneScoped 將托管 bean 指定為沒有范圍。無范圍的托管 bean 在被其他 bean 引用時(shí)比較有用。
@CustomScoped

在定制范圍內(nèi)存儲(chǔ)托管 bean。

定制范圍就是指可以由頁面創(chuàng)建者訪問的地圖。可以通過編程的方式控制定制范圍內(nèi)的 bean 的可視性和生命周期。 value 屬性指向一個(gè)地圖。

value

從 faces-config.xml 中移除托管 bean 聲明將極大地減少 XML,但是在 JSF 2 中,通過使用注釋(如我對(duì)托管 bean 所做的一樣)或是約定(比如 JSF 2 的簡(jiǎn)化的導(dǎo)航處理),幾乎可以去掉所有的 XML 內(nèi)容。





回頁首


技巧 2:簡(jiǎn)化導(dǎo)航

在 JSF 1 中,導(dǎo)航使用 XML 指定。比如,要從 login.xhtml 轉(zhuǎn)到 places.xhtml,可能使用清單 8 所示的導(dǎo)航規(guī)則:


清單 8. JSF 1 中的導(dǎo)航配置規(guī)則和用例
                    
<navigation-rule>
<navigation-case>
<from-view-id>/pages/login.xhtml</from-view-id>
<outcome>places</outcome>
<to-view-id>/pages/places.xhtml</to-view-id>
</navigation-case>
</navigation-rule>

要去除 清單 8 中的 XML,可以利用 JSF 2 的導(dǎo)航約定:JSF 將 .xhtml 添加到按鈕操作的末尾并加載該文件。這意味著不需要使用注釋或其他內(nèi)容,只需要使用約定就可以完整地避免編寫導(dǎo)航規(guī)則的需求。在清單 9 在,按鈕的操作是 places ,因此 JSF 加載 places.xhtml:


清單 9. 通過約定進(jìn)行導(dǎo)航
                    
<h:commandButton id="loginButton"
value="#{msgs.loginButtonText}"
action=" places "/>

對(duì)于 清單 9 來說,不需要任何導(dǎo)航 XML。清單 9 中的按鈕加載 places.xhtml,但是前提是該文件和按鈕所在的文件處于同一個(gè)目錄中。如果操作并沒有以斜杠( / )開頭,那么 JSF 認(rèn)為這是一個(gè)相對(duì)路徑。如果需要更加明確一點(diǎn),可以指定一個(gè)絕對(duì)路徑,如清單 10 所示:


清單 10. 使用絕對(duì)路徑的導(dǎo)航
                    
<h:commandButton id="loginButton"
value="#{msgs.loginButtonText}"
action=" /pages/places "/>

當(dāng)用戶激活 清單 10 中的按鈕時(shí),JSF 將加載 /pages/places.xhtml 文件。

默認(rèn)情況下,JSF 將從一個(gè) XHTML 頁面轉(zhuǎn)至另一個(gè) XHTML 頁面,但是通過指定 faces-redirect 參數(shù)可以重定向,如清單 11 所示:


清單 11. 通過重定向進(jìn)行導(dǎo)航
                    
<h:commandButton id="loginButton"
value="#{msgs.loginButtonText}"
action="places ?faces-redirect=true "/>





回頁首


技巧 3:使用 Groovy

Java 技術(shù)的最大優(yōu)勢(shì)并不是 Java 語言,而是 Java 虛擬機(jī)(JVM)。在 JVM 上運(yùn)行著強(qiáng)大、新穎和創(chuàng)新的語言,比如 Scala、JRuby 和 Groovy,這使您在編寫代碼時(shí)擁有了更多選擇。Groovy 這個(gè)名字有些奇怪,但是功能非常強(qiáng)大,融合了 Ruby、Smalltalk 和 Java 語言,它是這些語言中最為流行的一種語言(參見 參考資料 )。

使用 Groovy 的理由有很多。首先,它要比 Java 語言更加簡(jiǎn)潔、功能更加強(qiáng)大。還有兩個(gè)原因:不使用分號(hào),不需要強(qiáng)制轉(zhuǎn)換(casting)。

您可能還沒有注意到,在 清單 2 中, Place 類是使用 Groovy 編寫的。這一點(diǎn)可以通過代碼中沒有使用分號(hào)看出來,但是注意下面這行代碼: MapService ms = elResolver.getValue(...) 。對(duì)于 Java 代碼,我必須強(qiáng)制轉(zhuǎn)換 ElResolver.getValue() 的結(jié)果,因?yàn)樵摲椒ǚ祷仡愋? Object 。Groovy 可以為我自動(dòng)完成轉(zhuǎn)換。

可 以將 Groovy 用于任何使用 Java 代碼編寫的 JSF 工件 — 例如,組件、呈現(xiàn)器、驗(yàn)證器和轉(zhuǎn)換器。事實(shí)上,這對(duì)于 JSF 2 來說并不新鮮 — 因?yàn)?Groovy 源文件編譯為 Java 字節(jié)碼,您只需使用 Groovy 生成的 .class 文件,就好象它們是由 javac 生成的一樣。當(dāng)然,Groovy 生成的 .class 文件可以正常工作后,需要了解如何熱部署 Groovy 源代碼,并且對(duì)于 Eclipse 用戶,答案非常簡(jiǎn)單:下載并安裝 Groovy Eclipse 插件(參見 參考資料 )。Mojarra 是 Sun 的 JSF 實(shí)現(xiàn),從版本 1.2_09 之后提供了對(duì) Groovy 的明確支持(參見 參考資料 )。





回頁首


技巧 4:利用資源處理程序

JSF 2 提供了定義和訪問資源的標(biāo)準(zhǔn)機(jī)制。您將自己的資源放到名為 resources 的頂級(jí)目錄下,并使用一些 JSF 2 標(biāo)記來在視圖中訪問這些資源。例如,圖 4 展示了 places 應(yīng)用程序的資源:


圖 4. places 應(yīng)用程序的資源
places 應(yīng)用程序的資源

對(duì)資源的惟一需求是它必須位于 resources 目錄或 resources 目錄的子目錄中。可以隨意命名 resources 目錄的子目錄。

在您的視圖代碼中,可以使用兩個(gè) JSF 2 標(biāo)記訪問資源: <h:outputScript> <h:outputStylesheet> 。這些標(biāo)記可以結(jié)合用于 JSF 2 的 <h:head> <h:body> 標(biāo)記,如清單 12 所示:


清單 12. 在 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">

< h:head >
...
</ h:head >

< h:body >
< h:outputStylesheet library="css" name="styles.css" target="body"/>
< h:outputScript library="javascript" name="util.js" target="head"/>
...
</ h:body >
</html>

<h:outputScript> <h:outputStylesheet> 標(biāo)記有兩個(gè)屬性,分別指定了腳本或樣式表: library name library 名稱對(duì)應(yīng)于 resources 目錄下的子目錄,這是保存資源的位置。例如,如果在 resources/css/en 目錄中有一個(gè)樣式表,那么 library 將為 css/en name 屬性是資源本身的名稱。

可重新定位的資源

開 發(fā)人員需要能夠在頁面中指定想要呈現(xiàn)他們的資源的位置。例如,如果將 JavaScript 放在頁面體中,瀏覽器將在加載頁面時(shí)執(zhí)行 JavaScript。另一方面,如果將 JavaScript 放到頁面的頭部,那么 JavaScript 只有在得到調(diào)用時(shí)才會(huì)被執(zhí)行。由于資源的放置位置會(huì)影響它的使用方式,因此需要能夠指定希望在哪些位置顯示資源。

JSF 2 資源是 可重新定位的 ,這意味著您可以在頁面中指定希望放置資源的位置。您將使用 target 屬性指定位置;比如,在 清單 12 中,我將 CSS 放到頁面體中,而將 JavaScript 放到頁面頭部中。

有些情況下,需要使用 JSF 表達(dá)式語言(EL)訪問資源。比如,清單 13 展示了如何使用 <h:graphicImage> 訪問一個(gè)圖像:


清單 13. 使用 JSF 表達(dá)式語言訪問資源
                    
<h:graphicImage value="#{ resource['images:cloudy.gif'] }"/>

清單 13 的非 EL 備選方法

無可否認(rèn),清單 13 中的語法不是很直觀。它訪問了一個(gè) JSF 為了存儲(chǔ)資源而創(chuàng)建的地圖,因此很少需要使用這種語法。實(shí)際上,可以使用 <h:graphicImage/> 訪問圖像,而不需要使用 EL,比如: <h:graphicImage library="images" name="cloudy.gif"/>

在 EL 表達(dá)式內(nèi)訪問資源的語法是 resource[' LIBRARY : NAME '] ,其中 LIBRARY NAME 對(duì)應(yīng)于 <h:outputScript> <h:outputStylesheet> 標(biāo)記的 library name 屬性。




回頁首


結(jié)束語

到目前為止,我僅僅觸及了 JSF 2 特性中最淺顯的內(nèi)容,包括托管 bean、注釋、簡(jiǎn)化導(dǎo)航和資源支持。在本系列隨后的兩篇文章中,我將探討 Facelets、JSF 2 的復(fù)合組件以及對(duì) Ajax 的內(nèi)置支持。






回頁首


下載

描述 名字 大小 下載方法 源代碼
jsf2fu1.zip 1.9MB HTTP
關(guān)于下載方法的信息


參考資料

學(xué)習(xí)

獲得產(chǎn)品和技術(shù)

討論


關(guān)于作者

David Geary

David Geary 是一名作家、演講家和顧問,也是 Clarity Training, Inc. 的總裁,他指導(dǎo)開發(fā)人員使用 JSF 和 Google Web Toolkit (GWT) 實(shí)現(xiàn) Web 應(yīng)用程序。他是 JSTL 1.0 和 JSF 1.0/2.0 專家組的成員,與人合作編寫了 Sun 的 Web Developer 認(rèn)證考試的內(nèi)容,并且為多個(gè)開源項(xiàng)目作出貢獻(xiàn),包括 Apache Struts 和 Apache Shale。David 的 Graphic Java Swing 一直是有關(guān) Java 的暢銷書籍,而 Core JSF (與 Cay Horstman 合著)是有關(guān) JSF 的暢銷書。David 經(jīng)常在各大會(huì)議和用戶組發(fā)表演講。他從 2003 年開始就一直是 NFJS tour 的固定演講人,并且在 Java University 教授課程,兩次當(dāng)選為 JavaOne 之星。

轉(zhuǎn)自:http://www.ibm.com/developerworks/cn/java/j-jsf2fu1/

JSF 2 簡(jiǎn)介,第 1 部分: 流線化 Web 應(yīng)用程序開發(fā)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲国产片高清在线观看 | 国产成人在线视频播放 | 午夜欧美性欧美 | 亚洲精品久久AV无码蜜桃 | 亚洲高清视频在线 | 欧美一区二区三区播放 | 欧美特黄aaaaaa | 国产精品综合亚洲AV久久久小说 | 天天操天天干天天操 | 亚洲视频在线免费看 | 日韩在线电影 | 亚洲中午字幕 | 香蕉久 | 国内精品易阳在线播放国产 | 日产精品乱码卡一卡2卡三 久久99精品久久久久久综合 | 手机看片国产免费现在观看 | 91精品久久久久久久久久小网站 | 成人在线视频观看 | 国产亚洲成av人在线观看导航 | 九九51精品国产免费看 | 亚洲欧美中文日韩综合 | 亚洲欧美一区二区三区久本道 | 精品欧美一区二区在线观看欧美熟 | 久草视频在线观 | 国产乱偷国产偷高清 | 日本特黄特色大片免费视频 | 妞干在线 | 国产精品综合色区在线观看 | 99久久久久久国产精品 | 四虎免费在线观看视频 | 国产精品片一区二区三区 | 日本精品中文字幕有码 | 91免费版成人 | 午夜欧美一区二区三区在线播放 | 亚洲国产精品久久久久秋霞蜜臀 | A片太大太长太深好爽A片视频 | 男女无遮挡高清性视频直播 | 91拍拍在线观看 | 精品欧美一区二区三区在线 | 精品久久网 | 国产美女主播在线观看 |