日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

將struts程序移植到JSF

系統(tǒng) 1802 0

? 將Struts 應(yīng)用程序移植到 JSF

為了將 Struts Web 應(yīng)用程序與 JSF 集成,遵循以下步驟:

  • 將 struts-faces.jar 文件與特定于 JSF 的 JAR(jsf-api.jar、jsf-ri.jar) 添加到 Web 應(yīng)用程序的? WEB-INF/lib 目錄中。?
  • 如果準(zhǔn)備使用 JSF 和 JSTL,則將特定于 JSTL 的 JAR(jstl.jar、standard.jar)添加到? WEB-INF/lib ?文件夾中。這一步只有在部署到常規(guī) Tomcat 時(shí)才會(huì)需要。JWSDP 已經(jīng)提供了這些 JAR。?
  • 修改 Web 應(yīng)用程序部署描述符 (? /WEB-INF/web.xml )以便有一個(gè) Faces Servlet 項(xiàng), 如清單 5 所示。?
  • 修改 JSP 頁(yè)面以使用 JSF 和 Struts-Faces 標(biāo)記而不是 Struts 標(biāo)記。特別是用 Struts-Faces 相應(yīng)標(biāo)記替換? html、b ? ase、 ? form ?和? errors ?標(biāo)記。用 JSF 相應(yīng)標(biāo)記替換? text ?、? textarea ?和? radio ?標(biāo)記。Struts-Faces 沒(méi)有單獨(dú)針對(duì)這些的標(biāo)記。盡管沒(méi)有要求,但是您可能還會(huì)考慮用 JSTL 標(biāo)記替換 Struts Logic 標(biāo)記。?
  • 對(duì)于每一個(gè)使用 JSF 標(biāo)記的 JSP,修改 struts-config.xml 文件以在指向該 JSP 的 Action Mapping 中的? global-forwards 和? local-forwards 中加入前綴? /faces 。?
  • 如果 Web 應(yīng)用程序使用了任何您創(chuàng)建的自定義組件,那么您就需要用 JSF 實(shí)現(xiàn)的默認(rèn) RenderKit 注冊(cè)它們。可以通過(guò)在? WEB-INF ?文件中創(chuàng)建一個(gè) faces-config.xml 文件、并增加每一個(gè)組件和 renderer 的項(xiàng)做到這一點(diǎn)。不過(guò),要記住 faces-config.xml 文件已經(jīng)綁定在 struts-faces.jar 文件中了。您必須從 struts-faces.jar 文件中提出它、加入自己的內(nèi)容并將它放到? WEB-INF 文件夾中。


清單 5. 在 web.xml 中聲明 FacesServlet

?

<!-- JavaServer Faces Servlet Configuration -->
<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 -->
<servlet-mapping >
? <servlet-name > faces </servlet-name >
? <url-pattern > /faces/* </url-pattern >
</servlet-mapping >

集成 Struts-Faces 和 Tiles 的挑戰(zhàn)

Struts-Faces 庫(kù)提供了 Struts 與 JSF 之間的一個(gè)高效的橋梁,使得在 J2EE Web 應(yīng)用程序中擁有豐富的表示層成為現(xiàn)實(shí)。您可以通過(guò)在組合體中添加 Titles 使表示層更豐富,這樣不僅得到了 Struts 和 JSF 組合的好處,而且還可以高效地重復(fù)使用不同的 JSP 頁(yè)面,因?yàn)樗鼈儗⒂煽梢愿鶕?jù)需要添加或者刪除的組件部分或者 tiles 所構(gòu)成。

本文已經(jīng)展示了 Struts 和 JSP 的集成,您會(huì)想將 Tiles 加入到組合中只是小事一樁,是不是?

不幸的是,JSF 仍然處于早期階段,還沒(méi)有給出最后的發(fā)布。基于這一考慮,Struts-Faces 集成軟件開(kāi)發(fā)仍然在不斷地發(fā)展以包括 JSF 的不同的功能,并且還沒(méi)有支持 Tiles。

Struts 和 Tiles 可以無(wú)縫地共同工作,但是在集成之路上您會(huì)遇到路障。在下面幾小節(jié)中,您會(huì)看到在與 Tiles 共同使用 Struts-Faces 集成庫(kù)時(shí)經(jīng)常遇到的問(wèn)題的匯總。對(duì)于每一個(gè)問(wèn)題,我們?cè)敿?xì)說(shuō)明了一個(gè)修改 Struts-Faces 類的解決方案。我們將用一個(gè)航班搜索示例解釋這個(gè)解決方案。

清單 6 展示了航班搜索頁(yè)面的布局。注意我們稱它為航班搜索頁(yè)面而不是 FlightSearch.jsp。這是因?yàn)?FlightSearch JSP 是用戶在 foobar 旅行 Web 站點(diǎn)看到的合成頁(yè)面的主體。

現(xiàn)在,我們保持實(shí)際的 FlightSearch.jsp 不變。我們將隨著進(jìn)展改變它。在您這邊,也需要用航班搜索頁(yè)的定義創(chuàng)建一個(gè) Tiles 定義文件。清單 7(緊接著清單 6)展示了 Tiles 定義文件中航班搜索頁(yè)的一項(xiàng)。注意對(duì)帶有? extends ?屬性的主布局模板的重復(fù)使用。

在清單 6 和 7 后是每一個(gè)可能的挑戰(zhàn)。


清單 6. 航班搜索例子的 Tiles 布局

?

<%@ taglib uri= "/WEB-INF/struts-tiles.tld" prefix= "tiles" % >
<%@ taglib uri= "http://jakarta.apache.org/struts/tags-faces" prefix= "s" % >

<!-- Layout component parameters: header, menu, body, footer -->
<s :html>
<head>
? <title> <tiles:getAsString name = "title" / > </title>
? <s :base/ >
</head>
<body>
? <TABLE border = "0" width = "100%" cellspacing = "5" >
? ? <tr>
? ? ? <td> <tiles:insert attribute= "header" / > </td>
? ? </tr>

? ? <tr>
? ? ? <td> <tiles:insert attribute= "body" / > </td>
? ? </tr>

? ? <tr> <td> <hr> </td> </tr>

? ? <tr>
? ? ? <td> <tiles:insert attribute= "footer" / > </td>
? ? </tr>
? </TABLE>
</body>
</s :html>
<!-- Master Layout definition? -->
<definition name = "foobar.master-layout"
? path = "/faces/layout/MasterLayout.jsp" >

? ? ? <put name = "title" ? value = "Welcome to Foo Bar Travels" />
? ? ? <put name = "header" value = "/faces/common/header.jsp" />
? ? ? <put name = "footer" value = "/faces/common/footer.jsp" />
? ? ? <put name = "body" ? ? value = "" />
</definition >

? <!-- Definition for Flight Search Page -->
<definition name = "/foobar.flight-search"
? extends = "foobar.master-layout" >

? ? ? <put name = "body" ? ? value = "/faces/FlightSearch.jsp" />
</definition >

響應(yīng)已經(jīng)提交

這是您在試圖訪問(wèn)航班搜索表單時(shí)馬上會(huì)看到的第一個(gè)問(wèn)題。小心查看堆棧跟蹤。您會(huì)看到問(wèn)題出在類? com.sun.faces.lifecycle.ViewHandlerImpl ?上。這是一個(gè)實(shí)現(xiàn)了? ViewHandler ?接口的 JSF-RI 類。

圖 2 展示了? ViewHandler ?所扮演的角色。這是一個(gè)將請(qǐng)求轉(zhuǎn)發(fā)給下一頁(yè)的類。在轉(zhuǎn)發(fā)請(qǐng)求時(shí),它不在轉(zhuǎn)發(fā)前檢查響應(yīng)的狀態(tài) -- 這只有在使用 Tiles 時(shí)才會(huì)發(fā)生,因?yàn)?Tiles 內(nèi)部將 JSP 頁(yè)面包括在響應(yīng)內(nèi),而 JSF-RI 在第一次轉(zhuǎn)發(fā)后提交響應(yīng)、然后試圖再次轉(zhuǎn)發(fā)給下面的包括 JSP 的 Tiles。

要解決這個(gè)問(wèn)題,必須創(chuàng)建一個(gè)自定義的? ViewHandler ?實(shí)現(xiàn),它將檢查響應(yīng)的狀態(tài)以確定它是否提交過(guò)。如果響應(yīng)沒(méi)有提交過(guò),那么請(qǐng)求就轉(zhuǎn)發(fā)給下一頁(yè),否則,就加入請(qǐng)求并顯示相應(yīng)的 JSP。我們將創(chuàng)建一個(gè)名為? STFViewHandlerImpl ?的類,它實(shí)現(xiàn)了? ViewHandler ?接口并實(shí)現(xiàn)了所需要的方法? renderView()。 ?清單 8 展示了? STFViewHandlerImpl ?中的? renderView() ?方法:


清單 8. STFViewHandlerImpl 中的 renderView()方法

RequestDispatcher rd = null ;
Tree tree = context. getTree ( ) ;
String requestURI = context. getTree ( ) . getTreeId ( ) ;
rd = request. getRequestDispatcher ( requestURI ) ;

/** If the response is committed, include the resource **/
if ( !response. isCommitted ( ) ) {
? ?rd. forward ( request, context. getServletResponse ( ) ) ;
}
else {
? ?rd. include ( request, context. getServletResponse ( ) ) ;
}

現(xiàn)在您實(shí)現(xiàn)了自己的? ViewHandler ?,如何通知 JSF-RI 使用您的? ViewHandler ?而不是默認(rèn)的實(shí)現(xiàn)呢?要回答這個(gè)問(wèn)題,就必須理解? FacesServlet ?的工作過(guò)程。

在 Faces 初始化過(guò)程中,? FacesServlet ?會(huì)讓? LifecycleFactory ?實(shí)現(xiàn)返回? Lifecycle ?類的一個(gè)實(shí)現(xiàn),如清單 9 所示:


清單 9. FacesServlet 中 Faces 的初始化

?

//Get the LifecycleFactory from the Factory Finder
LifecycleFactory factory = ( LifecycleFactory )
? FactoryFinder. getFactory ( "javax.faces.lifecycle.LifecycleFactory" ) ;

//Get the context param from web.xml
String lifecycleID =
getServletContext ( ) . getInitParameter ( "javax.faces.lifecycle.LIFECYCLE_ID" ) ;

//Get the Lifecycle Implementation
Lifecycle lifecycle = factory. getLifecycle ( lifeCycleID ) ;

Lifecycle ?實(shí)現(xiàn)對(duì)象擁有在呈現(xiàn)響應(yīng)階段要使用的? ViewHandler ?。您可以通過(guò)對(duì)? Lifecycle ?實(shí)現(xiàn)調(diào)用? setViewHandler ?方法讓自己的? ViewHandler ?實(shí)現(xiàn)成為默認(rèn)的。

現(xiàn)在問(wèn)題變?yōu)槿绾蔚玫侥J(rèn)? Lifecycle ?實(shí)現(xiàn)?回答是不需要這樣做。只要?jiǎng)?chuàng)建一個(gè)新的實(shí)現(xiàn)并用一個(gè)惟一 ID 注冊(cè)它,如清單 10 所示:


清單 10. 注冊(cè)自定義 ViewHandler 和 Lifecycle

?

//Get the LifecycleFactory from the Factory Finder
LifecycleFactory factory = ( LifecycleFactory )
? FactoryFinder. getFactory ( "javax.faces.lifecycle.LifecycleFactory" ) ;

//Create a new instance of Lifecycle implementation -
//com.sun.faces.lifecycle.LifecycleImpl
//According to the documentation, factory.getLifecycle("STFLifecycle")
//should work, but JSF-RI has a defect.
//Hence this workaround of creating a RI class explicitly.
LifecycleImpl stfLifecycleImpl = new LifecycleImpl ( ) ;

//Create a new instance of our STFViewHandler and set it on the Lifecycle
stfLifecycleImpl. setViewHandler ( new STFViewHandlerImpl ( ) ) ;

//Register the new lifecycle with the factory with a unique
//name "STFLifecycle"
factory. addLifecycle ( "STFLifecycle" , stfLifecycleImpl ) ;
您可以看到? lifecycleId ?硬編碼為? STFLifecycle ?。實(shí)際上不是這樣。當(dāng)您回過(guò)頭分析? 清單 9 時(shí)就會(huì)清楚。? FacesServlet ?從在 web.xml 文件中聲明的上下文參數(shù)中得到名為? javax.faces.lifecycle.LIFECYCLE_ID ?的 lifecycle ID,如下所示:
?? ? <context-param >
? ? ? ? <param-name > javax.faces.lifecycle.LIFECYCLE_ID </param-name >
? ? ? ? <param-value > STFLifecycle </param-value >
? ? </context-param >

因?yàn)? FacesServlet ?取決于其初始化時(shí)的? Lifecycle ?實(shí)現(xiàn),在? 清單 10 中展示的代碼應(yīng)該在? FacesServlet ?初始化之前執(zhí)行。通過(guò)創(chuàng)建另一個(gè) servlet 并在? FacesServlet ?之前初始化它而做到這一點(diǎn)。

但是一種更聰明的辦法是實(shí)現(xiàn)一個(gè)? ServletContextListener ?接口。這個(gè)類聲明兩個(gè)方法:? contextInitialized() ?和? contextDestroyed() ?,在 Web 應(yīng)用程序被創(chuàng)建及 Web 應(yīng)用程序被銷(xiāo)毀之前會(huì)分別調(diào)用它們。因而? 清單 10 中的代碼在? contextInitialized() ?方法中執(zhí)行,而自定義? ViewHandler ?已經(jīng)用標(biāo)識(shí)名? STFLifecycle ?注冊(cè)到? Lifecycle ?,并且可被? FacesServlet ?使用。? ServletContextListener ?類本身是在 web.xml 文件中聲明的,如下所示:

<listener >
? <listener-class > foo.bar.stf.application.STFContextListener
? </listener-class >
</listener >

這不是注冊(cè)一個(gè)帶有自定義? ViewHandler ?的? Lifecycle ?惟一方法。事實(shí)上? FactoryFinder ?實(shí)現(xiàn)了自己的發(fā)現(xiàn)算法以發(fā)現(xiàn)? Factory ?對(duì)象,包括? LifecycleFactory ?。這些機(jī)制按照順序包括在系統(tǒng)屬性中查看工廠實(shí)現(xiàn)類名的機(jī)制、faces.properties file、或者 1.3 Services 發(fā)現(xiàn)機(jī)制(? META-INF/services/{factory-class-name} ?)。不過(guò),我們討論的這種機(jī)制是最容易的,也是最不具有破壞性的一種。

404 Resource Not Found

在解決了提交響應(yīng)的問(wèn)題后,單擊任何一個(gè) Tiles 特定的鏈接或者輸入一個(gè)會(huì)呈現(xiàn) Faces 響應(yīng)的 URL。在這里,可以輸入顯示? FlightSearchForm ?的 URL。

在這樣做了以后,您會(huì)得到一個(gè)? foobar.flight-search - 404 Resource Not Found ?錯(cuò)誤。? foobar.flight-search ?是航班搜索頁(yè)面的 Tiles 定義的名字。? FacesRequestProcessor ?不能處理 Tiles 請(qǐng)求(因?yàn)樗鼣U(kuò)展的是 RequestProcessor ?而不是? TilesRequestProcessor ?),所以會(huì)得到錯(cuò)誤。

為解決這個(gè)問(wèn)題,我們將創(chuàng)建一個(gè)名為? STFRequestProcessor ?(表示? Struts-Tiles-Faces Request Processor )的新的請(qǐng)求處理程序。現(xiàn)在我們將拷貝? FacesRequestProcessor ?的所有代碼到這個(gè)新類中。惟一的區(qū)別是? STFRequestProcessor ?繼承的是? TilesRequestProcessor ?而不是繼承常規(guī)的? RequestProcessor ?。這個(gè)新的? RequestProcessor ?可以處理 Tiles 請(qǐng)求。清單 11 詳細(xì)列出了這個(gè)? STFRequestProcessor ?:


清單 11. STFRequestProcessor.java

正如您所知道的,? Struts ?框架的? RequestProcessor ?是在 struts-config.xml 文件中指定的。將下面的項(xiàng)添加到? struts-cinfig.xml? 文件中后,? STFRequestProcessor ?就成為處理程序:

<controller processorClass="foobar.stf.application.STFRequestProcessor" />

表單提交顯示返回同一個(gè)表單

由于? STFRequestProcessor ?的作用,這時(shí)您就可以瀏覽并查看航班頁(yè)面了。不過(guò),在提交航班搜索表單時(shí),您會(huì)得到返回來(lái)的同一個(gè)表單,而且沒(méi)有頁(yè)頭和頁(yè)腳!并且沒(méi)有驗(yàn)證錯(cuò)誤。事實(shí)上,根本就沒(méi)有進(jìn)行驗(yàn)證!

為了了解到底發(fā)生了什么事情,我們用瀏覽器回到航班頁(yè)面并檢查 HTML 源代碼。您會(huì)看到像下面這樣的一項(xiàng):

?

                      
                        <form name="FlightSearchForm" method="post"    action="/flightapp/faces/FlightSearch.jsp">  
                      
                    

?

注意表單 action 是指向 JSP 頁(yè)而不是一個(gè)? .do ?的。啊哈!這就是問(wèn)題!這不是由于同時(shí)使用 Tiles 和 Struts-Faces 而帶來(lái)的新問(wèn)題,Struts-Faces 的默認(rèn)行為是讓 JSP 與表單 action 有同樣的名字。這種行為在有單一的 JSP 頁(yè)(如在前面的 Struts-Faces 例子中)時(shí)沒(méi)有問(wèn)題。? 清單 3 展示了原來(lái)的 FlightSearch.jsp,讓我們繼續(xù)并像下面這樣修改 action:

?

                      
                        <s:form action="/listFlights.do> 
                      
                    

?

當(dāng)然,光有這種修改并不能解決問(wèn)題。作了這種改變后,您就會(huì)發(fā)現(xiàn)? STFRequestProcessor ?不能找到? ActionForm ?。顯然還需要其他的改變。

不過(guò),在繼續(xù)往下之前,看一下圖&#160 5。它顯示了在呈現(xiàn)負(fù)責(zé) Struts-Faces 表單的 faces 時(shí)相關(guān)的一系列事件。這與? 圖 3 相同,除了在? FormComponent ?中突出顯示的方法? createActionForm()。 ?由 Struts-Faces API 提供的? FormComponent ?類是? javax.faces.component.UIForm ?的特殊子類,它支持請(qǐng)求或者會(huì)話范圍的表單 Bean。

圖 5. 呈現(xiàn) Struts-Faces 響應(yīng) ?
單擊這里 以查看該圖。

正如您所看到的,? createActionForm() ?方法使用 action 名以從 Struts 配置文件中得到? ActionMapping ?。因?yàn)闆](méi)有對(duì)于? /listFlights.do ?的? ActionMapping ?,所以 Struts 不能找到? ActionForm。

這個(gè)問(wèn)題的解決方法是使用? org.apache.struts.util.RequestUtils ?。? RequestUtils ?中的 static 方法? getActionMappingName() ?具有足夠的智能解析映射到正確? ActionMapping ?的路徑(? /x/y/z )或者后綴(? .do )。

清單 12 以粗體顯示對(duì)? createActionForm ?方法的改變。我們沒(méi)有對(duì) Struts-Faces 中的? FormComponent ?作這些改變,而是通過(guò)繼承? FormComponent ?并覆蓋? createActionForm()? 方法創(chuàng)建了一個(gè)新的? STFFormComponent。


清單 12. FormComponent 中修改過(guò)的 createActionForm() 方法

                      
                        // Look up the application module configuration information we need ModuleConfig moduleConfig = lookupModuleConfig(context);  // Look up the ActionConfig we are processing String action = getAction(); String mappingName = RequestUtils.getActionMappingName(action); ActionConfig actionConfig = moduleConfig.findActionConfig(mappingName); .... .... 
                      
                    

?

對(duì)新的? STFFormComponent ?還要作一項(xiàng)改變。Struts-Faces 將 action 名本身作為表單名。這需要改變,因?yàn)?action 帶有后綴? .do ,而表單名沒(méi)有后綴? .do 。所以我們?cè)? STFFormComponent ?上增加一個(gè)名為? action 的新屬性,并覆蓋? getAction() ?和? setAction() ?方法。

FormRenderer 的改變

必須對(duì)? FormRenderer ?(以 HTML 格式呈現(xiàn) Struts-Faces 表單的類)的? encodeBegin ?方法進(jìn)行類似于? 清單 10 所示的修改。

同樣,通過(guò)繼承? FormRenderer ?做到這一點(diǎn)。此外,還必須改變寫(xiě)出到 HTML 的表單 action。清單 13以粗體詳細(xì)列出了這些改變:


清單 13. FormRenderer 的改變

                      
                        protected String action(FacesContext context, UIComponent component) {      String treeId = context.getTree().getTreeId();     StringBuffer sb = new StringBuffer        (context.getExternalContext().getRequestContextPath());     sb.append("/faces");      // sb.append(treeId); -- This is old code, replaced with      // the two lines below.      STFFormComponent fComponent = (STFFormComponent) component;     sb.append(fComponent.getAction());          return (context.getExternalContext().encodeURL(sb.toString())); } 
                      
                    

?

FormTag 的改變?
正如您已經(jīng)知道的,當(dāng)組件和 renderer 改變時(shí),標(biāo)記也必須改變。在這里,通過(guò)繼承 Struts-Faces 中的? FormTag ?創(chuàng)建一個(gè)新的標(biāo)記:? STFFormTag ?。不必改變?nèi)魏喂δ埽灰采w? getComponentType() ?和? getRendererType() ?方法。清單 14 展示了從? STFFormComponent ?覆蓋的方法:


清單 14. FormTag 的改變

                      
                        public String getComponentType() {     return ("STFFormComponent"); }  public String getRendererType() {     return ("STFFormRenderer"); }  
                      
                    

?

修改 faces-config.xml 文件

自定義組件和 renderer 必須在 faces-config.xml 文件中聲明,這樣 JSF 框架才可以初始化并使用它們。現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè)新組件? STFFormComponent ?和一個(gè)新 renderer? STFFormRenderer ?。

現(xiàn)在我們將在 faces-config.xml 文件中增加一個(gè)聲明,如清單 15 所示。? component-class ? 是組件的完全限定類名。? component-type ?指的是在? STFFormTag ?(? 清單 12 )中用于標(biāo)識(shí)組件的名字。以類似的方式發(fā)現(xiàn)和解釋 renderer。注意 faces-config.xml 文件是在 struts-faces.jar 文件中的。從 struts-faces.jar 文件中取出這個(gè)文件并將它放到 Web 應(yīng)用程序的? WEB-INF 文件夾中并修改它。


清單 15. 在 faces-config.xml 中聲明自定義組件和 renderer

                      
                        <faces-config>    <!-- Custom Components -->   <component>      <component-type>STFFormComponent</component-type>     <component-class>       foobar.stf.component.STFFormComponent     </component-class>   </component>   ..   ..   ..   <!-- Custom Renderers -->    <render-kit>      <renderer>       <renderer-type>STFFormRenderer</renderer-type>       <renderer-class>         foobar.stf.renderer.STFFormRenderer       </renderer-class>      </renderer>     ..     ..     ..   </render-kit> </faces-config> 
                      
                    

?

修改 struts-faces.tld 文件

您不會(huì)在這個(gè)示例 Struts-Faces 應(yīng)用程序中看到 struts-faces.tld 文件,它打包到了 struts-faces.jar 文件中。打開(kāi)并分析這個(gè)文件。它聲明了一個(gè)名為? org.apache.struts.faces.taglib.LifecycleListener ?的類,這個(gè)類實(shí)現(xiàn)了? ServletContextListener ?并初始化? FacesRequestProcessor ?。

因?yàn)橄M褂眯碌? STFRequestProccessor ?,所以必須將這個(gè)文件從 struts-faces.jar 文件中刪除,將它放到 Web 應(yīng)用程序的? WEB-INF ?文件夾中,并刪除偵聽(tīng)器聲明。如果讓這個(gè) tld 文件保持原樣,那么在初始化這個(gè) Web 應(yīng)用程序時(shí),除了? STFRequestProcessor ?,還會(huì)實(shí)例化一個(gè)? FacesRequestProcessor。

修改 base href 標(biāo)記?
現(xiàn)在,您已經(jīng)完成了 Struts、Tiles、JSF 集成的最困難的部分了。您甚至可以瀏覽航班搜索頁(yè)面,并輸入搜索標(biāo)準(zhǔn)查看航班列表。現(xiàn)在試著從航班列表頁(yè)面返回航班搜索表單。您會(huì)得到一個(gè) HTTP 400 錯(cuò)誤。這個(gè)錯(cuò)誤的原因是 HTML? base href ?標(biāo)記。它被設(shè)置為 Master Layout 頁(yè)面。

?

                      
                        <base href=   "http://localhost:8080/stf-example/faces/layout/MasterLayout.jsp" />            |_________|       |_____________________|               Context               Servlet Path 
                      
                    

?

程序所有頁(yè)面瀏覽都是相對(duì)于布局頁(yè)面計(jì)算的。如果加入的? base href ?標(biāo)記只達(dá)到 Web 應(yīng)用程序上下文則會(huì)很方便,像這樣:

?

                      
                        <base href="http://localhost:8080/stf-example/" />  
                      
                    

?

我們可以通過(guò)定制 Struts-Faces? BaseTag ?做到這一點(diǎn)。這個(gè)類中的改變相當(dāng)微不足道。只須在 base href 中去掉? HttpServletRequest.getServletPath() ?。

因?yàn)檫@些改變是與顯示相關(guān)的,所以為它創(chuàng)建了一個(gè)名為? STFBaseRenderer ?的新 renderer。這個(gè)新標(biāo)記稱為? STFBaseTag ?,它聲明? STFBaseRenderer ?作為其關(guān)聯(lián)的 renderer。不需要新的組件。

有了這些信息,通過(guò)繼承? BaseTag ?并覆蓋? getRendererType ?方法創(chuàng)建新的? STFBaseTag ?,如下所示:

?

                      
                        public String getRendererType() {     return ("STFBaseRenderer"); } 
                      
                    

?

到目前為止所作的改變

恭喜!經(jīng)過(guò)這些相對(duì)較小的修改,您已經(jīng)成功地集成了 Struts、Tiles 和 JSF,并保留了您以前在這些技術(shù)上所做的所有投資。本文演示了如何將 JSF 強(qiáng)大的前端能力、 Tiles 的內(nèi)容格式編排優(yōu)勢(shì)以及 Struts 控制器層的靈活性結(jié)合在一個(gè)包中,使得創(chuàng)建一個(gè) J2EE Web 應(yīng)用程序成為一項(xiàng)更容易的任務(wù)。

padding-top: 0px; padding-right: 0px; padding-left: 0px; padding-bottom: 6px; clear: both; text-align: left; margin-top: 0px; margin-right: 0px; marg

分享到:
評(píng)論
pokerwen
  • 瀏覽: 30693 次
  • 性別: Icon_minigender_1
  • 來(lái)自: 深圳
最近訪客 更多訪客>>
最新評(píng)論

將struts程序移植到JSF


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

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

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

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

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 阿合奇县| 澎湖县| 宜城市| 历史| 凤翔县| 金华市| 奈曼旗| 洛浦县| 乌恰县| 鹤峰县| 横峰县| 介休市| 财经| 隆昌县| 襄樊市| 阿拉尔市| 犍为县| 呼伦贝尔市| 右玉县| 杂多县| 连江县| 张掖市| 普兰店市| 大方县| 平谷区| 宝丰县| 祁阳县| 张掖市| 隆子县| 斗六市| 凉城县| 甘肃省| 彩票| 张掖市| 从化市| 庐江县| 吴江市| 长海县| 香港 | 赤壁市| 克拉玛依市|