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