javascript
JSF的工作方式和调试方式–可以使用polyglot吗?
JSF不是我們通常認為的那樣。 這也是一個調(diào)試起來可能有些棘手的框架,尤其是在初次遇到時。 在這篇文章中,讓我們繼續(xù)探討為什么會出現(xiàn)這種情況,并提供一些JSF調(diào)試技術(shù)。 我們將討論以下主題:
- JSF不是我們經(jīng)常想到的
- JSF調(diào)試的難點
- 如何系統(tǒng)地調(diào)試JSF
- JSF的工作原理– JSF生命周期
- 從瀏覽器調(diào)試Ajax請求到服務(wù)器再返回
- 調(diào)試JSF前端Javascript代碼
- 最后的想法–替代方案? (給讀者的問題)
JSF不是我們經(jīng)常想到的
首先,JSF看起來像一個企業(yè)Java / XML前端框架,但實際上并不是 。 它實際上是一個多語言Java / Java腳本框架,其中客戶端Java腳本部分不可忽視,并且理解它也很重要。 它還對直接使用HTML / CSS有很好的支持。
JSF開發(fā)人員正在使用ocasion,而他們已經(jīng)是多種語言的開發(fā)人員,其主要語言是Java,但仍需要使用本地語言的Javascript。
JSF調(diào)試的難點
在上一篇文章中將JSF與GWT和AngularJS進行比較時 ,我發(fā)現(xiàn)該框架從XML背后的開發(fā)人員那里提取HTML和CSS的(最常用的)方法增加了調(diào)試的難度,因為它創(chuàng)建了一個額外的層次。間接。
也可以使用直接使用HTML / CSS的更直接的方法 ,但是似乎企業(yè)Java開發(fā)人員在大多數(shù)情況下傾向于使用XML,因為它是一種更熟悉的技術(shù)。 另一個問題是框架/庫的客戶端Javascript部分沒有很好的文檔記錄,了解發(fā)生的事情通常很重要。
系統(tǒng)調(diào)試JSF的唯一方法
第一次遇到JSF時,我首先嘗試僅從Java,XML和文檔中使用它。 雖然我可以那樣做一部分工作,但在很多情況下這種方法確實是不夠的。
我得出的結(jié)論是,為了能夠有效地調(diào)試JSF應(yīng)用程序,需要了解以下內(nèi)容:
- HTML
- CSS
- Java腳本
- HTTP
- Chrome開發(fā)工具,Firebug或同等功能
- JSF生命周期
對于大多數(shù)使用Java / XML進行工作的開發(fā)人員來說,這聽起來可能令人驚訝,但是這種以Web為中心的調(diào)試JSF的方法是我設(shè)法滿足許多需要一些重要組件自定義或能夠修復(fù)某些bug的唯一方法。
讓我們首先了解JSF的內(nèi)部工作原理,以便我們可以對其進行更好的調(diào)試。
JSF接受MVC
JSF處理MVC的方式是全部三個組件都位于服務(wù)器端:
- 該模型是純Java對象的樹
- 視圖是用XML定義的服務(wù)器端模板,可以讀取它以構(gòu)建內(nèi)存視圖定義
- Controller是一個Java Servlet,它接收每個請求并通過一系列步驟處理它們
假定瀏覽器只是服務(wù)器端生成HTML的呈現(xiàn)引擎。 通過提交頁面的一部分以進行服務(wù)器處理,并請求服務(wù)器僅在不離開頁面的情況下“重繪”屏幕的某些部分,即可實現(xiàn)Ajax。
JSF生命周期
HTTP請求到達后端后,將被JSF Controller捕獲,然后將對其進行處理。 該請求經(jīng)歷了稱為JSF生命周期的一系列階段,這對于理解JSF的工作方式至關(guān)重要:
JSF生命周期的設(shè)計目標
整個生命周期的重點是僅使用瀏覽器作為呈現(xiàn)平臺,在服務(wù)器端100%管理MVC。
最初的想法是使呈現(xiàn)平臺與服務(wù)器端UI組件模型脫鉤,以便通過交換“呈現(xiàn)響應(yīng)”階段來用替代標記語言替換HTML。
這是在2000年代初期,當時HTML很快就可以被基于XML的替代方法取代(但從未出現(xiàn)),然后HTML5出現(xiàn)了。 瀏覽器的功能要比當今更加強大,并且跨瀏覽器的Javascript庫的想法尚未普及。
因此,讓我們遍歷每個階段,看看如何從瀏覽器開始進行調(diào)試(如果需要)。 讓我們以使用Ajax請求的簡單示例為基礎(chǔ)。
JSF 2 Hello World示例
以下是最小的JSF 2頁面,該頁面接收來自用戶的輸入文本,通過Ajax請求將文本發(fā)送到后端,并僅刷新輸出標簽:
<h:body> <h3>JSF 2.2 Hello World Example</h3><h:form><h:outputtext id="output" value="#{simpleFormBean.inputText}"></h:outputtext> <h:inputtext id="input" value="#{simpleFormBean.inputText}"></h:inputtext><h:commandbutton value="Submit" action="index"><f:ajax execute="input" render="output"></f:ajax></h:commandbutton></h:form> </h:body>該頁面如下所示:
遵循一個Ajax請求–發(fā)送至服務(wù)器并返回
讓我們單擊提交以觸發(fā)Ajax請求,然后使用Chrome開發(fā)工具網(wǎng)絡(luò)標簽(右鍵單擊并檢查頁面上的任何元素)。 這是我們在請求的“表單數(shù)據(jù)”部分中看到的:
j_idt8:input: Hello World javax.faces.ViewState: -2798727343674530263:954565149304692491 javax.faces.source: j_idt8:j_idt9 javax.faces.partial.event: click javax.faces.partial.execute: j_idt8:j_idt9 j_idt8:input javax.faces.partial.render: j_idt8:output javax.faces.behavior.event: action javax.faces.partial.ajax:true該請求說:
輸入字段的新值是“ Hello World”,僅將輸出字段的新值發(fā)送給我,請勿瀏覽此頁面。
讓我們看看如何從請求中讀取它。 如我們所見,表單的新值被提交到服務(wù)器,即“ Hello World”值。 這是幾個條目的含義:
- javax.faces.ViewState標識從其發(fā)出請求的視圖。
- 該請求是一個Ajax請求,如標志javax.faces.partial.ajax ,
- 該請求是由javax.faces.partial.event定義的單擊觸發(fā)的。
但是,這些j_字符串是什么? 這些是用空格分隔生成HTML元素標識符。 例如,這是我們使用Chrome開發(fā)工具查看與j_idt8:input對應(yīng)的頁面元素的方式:
還有3個額外的表單參數(shù)使用這些標識符,這些參數(shù)鏈接到UI組件:
- javax.faces.source :發(fā)起此請求HTML元素的標識符,在本例中為Submit按鈕的ID。
- javax.faces.execute :元素的標識符列表,這些元素的值發(fā)送到服務(wù)器進行處理,在這種情況下為輸入文本字段。
- javax.faces.render :頁面上要“重畫”的部分的標識符列表,在這種情況下,僅是輸出字段。
但是,當請求到達服務(wù)器時會發(fā)生什么呢?
JSF生命周期–還原視圖階段
請求到達服務(wù)器后,JSF控制器將檢查
javax.faces.ViewState并標識它引用的視圖。 然后它將構(gòu)建或還原視圖的Java表示,該表示與瀏覽器端的文檔定義在某種程度上相似。
該視圖將附加到請求并在整個過程中使用。 通常在應(yīng)用程序開發(fā)期間幾乎不需要調(diào)試此階段。
JSF生命周期–應(yīng)用請求值
然后,JSF控制器將通過請求接收到的新值應(yīng)用于視圖小部件。 該值此時可能無效。 在此階段,每個JSF組件都會調(diào)用其decode方法。
此方法將從HTTP請求中檢索相關(guān)小部件的提交值,并將其存儲在小部件本身上。
為了調(diào)試它,讓我們在HtmlInputText類的decode方法中放置一個斷點,以查看值“ Hello World”:
注意使用所需字段HTML clientId的條件斷點。 這樣,即使在帶有許多其他相似小部件的大頁面中,也可以僅快速調(diào)試所需組件的解碼。 解碼之后的下一個步驟是驗證階段。
JSF生命周期–流程驗證
在此階段,將應(yīng)用驗證,如果發(fā)現(xiàn)值有誤(例如,日期無效),則請求將繞過“調(diào)用應(yīng)用程序”并直接進入“渲染響應(yīng)”階段。
要調(diào)試此階段,可以在processValidators方法上放置一個類似的斷點,或者,如果您碰巧知道哪些是自定義的,則可以在驗證器本身上放置。
JSF生命周期–更新模型
在此階段,我們知道所有提交的值都是正確的。 JSF現(xiàn)在可以通過將請求中接收到的新值應(yīng)用于視圖模型中的純Java對象來更新視圖模型。
通過在相關(guān)組件的processUpdates方法中放置一個斷點,最終使用類似的條件斷點僅在所需的組件上進行中斷,可以調(diào)試此階段。
JSF生命周期–調(diào)用應(yīng)用程序
這是最簡單的調(diào)試階段。 該應(yīng)用程序現(xiàn)在具有更新的視圖模型,并且可以在其上應(yīng)用一些邏輯。
這是在XML視圖定義中定義的動作偵聽器(“動作”屬性和偵聽器標記)執(zhí)行的地方。
JSF生命周期–渲染響應(yīng)
這是我最后調(diào)試最多的階段:為什么未按預(yù)期顯示該值,等等,都可以在這里找到。 在此階段,視圖和新模型值將從Java對象轉(zhuǎn)換為HTML,CSS和最終的Javascript,并通過電線發(fā)送回瀏覽器。
可以使用相關(guān)組件的encodeBegin , encodeChildren和encodeEnd方法中的斷點來調(diào)試此階段。
組件將自己渲染或?qū)秩疚薪oRenderer類。
回到瀏覽器
這是一段漫長的旅程,但我們回到了起點! 這是瀏覽器收到JSF生成的響應(yīng)后的樣子:
<!--?xml version='1.0' encoding='UTF-8'?--> <partial-response> <changes><update id="j_idt8:output"><span id="j_idt8:output"></span></update><update id="javax.faces.ViewState">-8188482707773604502:6956126859616189525></update></changes> </partial-response>框架的Javascript部分將要做的是獲取部分響應(yīng)的內(nèi)容,并逐個更新。
使用更新的ID,客戶端JSF回調(diào)將搜索具有該ID的組件,將其從文檔中刪除,然后將其替換為新的更新版本。
在這種情況下,“ Hello World”將顯示在“輸入”文本字段旁邊的標簽上!
因此,這就是JSF在后臺運行的方式。 但是,如果我們需要調(diào)試框架的Javascript部分,該怎么辦?
調(diào)試JSF Javascript代碼
Chrome開發(fā)工具可以幫助調(diào)試客戶端。 例如,假設(shè)我們要在觸發(fā)Ajax請求時暫停客戶端。 我們需要轉(zhuǎn)到“源”選項卡,添加XHR(Ajax)斷點并觸發(fā)瀏覽器操作。 調(diào)試器將停止,并且可以檢查調(diào)用堆棧:
對于諸如Primefaces之類的某些框架,可能會縮小Javascript源(人類不可讀),因為它們針對大??小進行了優(yōu)化。
要解決此問題,請下載該庫的源代碼,并以最小的方式構(gòu)建jar。 通常對此有說明,否則請檢查項目poms。 這將在您的Maven資源庫中安裝一個具有非最小化源的jar進行調(diào)試。
UI調(diào)試標簽:
ui:debug標記允許使用鍵盤快捷鍵查看許多調(diào)試信息,有關(guān)更多詳細信息,請參見此處 。
最后的想法
JSF在企業(yè)Java世界中非常流行,并且可以很好地處理許多問題,特別是在UI設(shè)計人員考慮使用小部件庫的可能性的情況下。
問題在于,通常會有一些功能請求迫使我們深入研究小部件的內(nèi)部實現(xiàn)以對其進行自定義,這需要HTML,CSS,Javascript和HTTP以及JSF生命周期知識。
雜音是替代品嗎?
我們想知道,如果開發(fā)人員必須對Web技術(shù)有足夠的了解,以便能夠有效地調(diào)試JSF,那么使用這些技術(shù)直接構(gòu)建企業(yè)前端(僅是客戶端部分)會更簡單。
可能會在不久的將來證明Java后端加上僅Javascript前端的多語言方法有效,特別是使用某種客戶端MVC框架(例如Angular) 。
這將需要學(xué)習(xí)更多的Javascript(如果好奇的話,可以看一下Java開發(fā)人員的Javascript ),但是無論如何,這對于在JSF中進行自定義小部件開發(fā)通常是必需的。
結(jié)論和一些疑問(如果有時間的話)
感謝您的閱讀,請花點時間在下面的評論中分享您對這些問題的看法:
- 您是否認為多語種開發(fā)(Java / Javascript)通常是可行的選擇,尤其是在您的工作場所中?
- 您是否發(fā)現(xiàn)基于GWT的框架之一(普通GWT,Vaadin,Errai)或Play框架更易于使用且具有更高的生產(chǎn)率?
翻譯自: https://www.javacodegeeks.com/2014/09/how-jsf-works-and-how-to-debug-it-is-polyglot-an-alternative.html
總結(jié)
以上是生活随笔為你收集整理的JSF的工作方式和调试方式–可以使用polyglot吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaOne 2014:会议与合同利益
- 下一篇: 初级开发人员在编写单元测试时常犯的错误