簡體   English   中英

JSF 返回帶有普通/原始 XHTML/XML/EL 源而不是呈現的 HTML 輸出的空白/未解析頁面

[英]JSF returns blank/unparsed page with plain/raw XHTML/XML/EL source instead of rendered HTML output

我有一些如下所示的 Facelets 文件。

WebContent
 |-- index.xhtml
 |-- register.xhtml
 |-- templates
 |    |--userForm.xhtml
 |    `--banner.xhtml
 :

兩個頁面都使用/templates目錄中的/templates 我的/index.xhtml在瀏覽器中打開正常。 我得到生成的 HTML 輸出。 我在/index.xhtml文件中有一個指向/register.xhtml文件的鏈接。

但是,我的/register.xhtml沒有被解析並返回為純 XHTML/原始 XML,而不是其生成的 HTML 輸出。 #{...}形式的所有 EL 表達式都按原樣顯示,而不是打印它們的結果。 當我在瀏覽器中右鍵單擊頁面並執行View page source 時,我仍然看到原始的 XHTML 源代碼而不是生成的 HTML 輸出。 例如, <h:body>沒有變成<body> 看起來模板沒有被執行。

但是,當我在瀏覽器的地址欄中打開像/faces/register.xhtml這樣的/register.xhtml時,它會正確顯示。 這是怎么引起的,我該如何解決?

主要有以下三個原因。

  1. FacesServlet沒有被調用。
  2. XML 命名空間 URI 丟失或錯誤。
  3. 已加載多個 JSF 實現。

1. 確保 URL 匹配FacesServlet映射

鏈接的 URL(您在瀏覽器地址欄中看到的 URL)必須與web.xml中定義的FacesServlet<url-pattern>匹配,以便讓所有 JSF 工作運行。 FacesServlet負責解析 XHTML 文件、收集提交的表單值、執行轉換/驗證、更新模型、調用操作和生成 HTML 輸出。 如果您不通過 URL 調用FacesServlet ,那么您將獲得的(通過右鍵單擊查看,在瀏覽器中查看源代碼)確實是原始 XHTML 源代碼。

如果<url-pattern>是例如*.jsf ,那么鏈接應該指向/register.jsf而不是/register.xhtml 如果它是例如/faces/* ,就像你一樣,那么鏈接應該指向/faces/register.xhtml而不是/register.xhtml 避免這種混淆的一種方法是將<url-pattern>/faces/*更改為*.xhtml 因此,以下是理想的映射:

<servlet>
    <servlet-name>facesServlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>facesServlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

如果由於某種原因您不能將<url-pattern>更改為*.xhtml ,那么您可能還想阻止最終用戶通過 URL 直接訪問 XHTML 源代碼文件。 在這種情況下,您可以在*.xhtml<url-pattern> <security-constraint>上添加一個<security-constraint>並在web.xml添加一個空的<auth-constraint>以防止:

<security-constraint>
    <display-name>Restrict direct access to XHTML files</display-name>
    <web-resource-collection>
        <web-resource-name>XHTML files</web-resource-name>
        <url-pattern>*.xhtml</url-pattern>
    </web-resource-collection>
    <auth-constraint />
</security-constraint> 

2017 年 4 月推出的 JSF 2.3 通過在 webapp 啟動期間自動在*.xhtml的 URL 模式上注冊FacesServlet已經解決了上述所有問題。 因此,替代方法是簡單地升級到最新的可用 JSF 版本,該版本應該是 JSF 2.3 或更高版本。 但理想情況下,您仍然應該僅在*.xhtml一種 URL 模式上顯式注冊FacesServlet ,因為對於完全相同的資源(如/register.xhtml/register.jsf/register.faces/faces/register.xhtml有多個可能的 URL對 SEO 不利。

也可以看看:


2. 確保 XML 命名空間匹配 JSF 版本

自從引入 JSF 2.2 以來,另一個可能的原因是 XML 名稱空間與 JSF 版本不匹配。 如下所示的xmlns.jcp.org是自 JSF 2.2 以來的新內容,並且不適用於較舊的 JSF 版本。 症狀幾乎與未調用FacesServlet相同。

<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

如果您無法升級到 JSF 2.2 或更高版本,則需要改用舊的java.sun.com XML 命名空間:

<html lang="en"
    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">

但理想情況下,您應該始終使用可用的最新版本。

也可以看看:


3. 加載了多個 JSF 實現

另一個可能的原因是您的 web 應用程序加載了多個 JSF 實現,相互沖突和損壞。 例如,當您的 webapp 的運行時類路徑被多個不同版本的 JSF 庫污染時,或者在特定的 Mojarra 2.x + Tomcat 8.x 組合中,當 webapp 的web.xml有一個不必要的ConfigureListener條目導致它被加載兩次時。

<!-- You MUST remove this one from web.xml! -->
<!-- This is actually a workaround for buggy GlassFish3 and Jetty servers. -->
<!-- When leaving this in and you're targeting Tomcat, you'll run into trouble. -->
<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

使用 Maven 時,請務必確保以正確的方式聲明依賴項並了解依賴項范圍。 重要的是,當目標服務器已經提供依賴項時,不要在 webapp 中捆綁依賴項。

也可以看看:


確保您以正確的方式學習 JSF

對於那些不熟悉基本HTTPHTMLServlets 的人來說,JSF 的學習曲線非常陡峭。 互聯網上有很多低質量的資源。 請忽略由業余愛好者維護的主要關注廣告收入而不是教學的代碼片段抓取網站,例如 roseindia、tutorialspoint、javabeat、baeldung 等。它們很容易通過干擾廣告鏈接/橫幅識別。 另外請忽略處理侏羅紀 JSF 1.x 的資源。 通過使用 JSP 文件而不是 XHTML 文件,它們很容易識別。 自 2009 年的 JSF 2.0 以來,JSP 作為視圖技術已被棄用。

要以正確的方式開始,請從我們的 JSF wiki 頁面開始並訂購一本權威書籍

也可以看看:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM