Javaserver Faces 2.2 and Html5 Support, Why Is Xhtml Still Being Used

JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used

It seems that you misunderstood the purpose of XHTML like as many people during the XHTML overhype a couple of years ago. Long story short: check our XHTML wiki page. Carefully read it. In a nutshell, Facelets absolutely doesn't care about the doctype being used in the generated HTML output. You can perfectly fine declare a HTML5 doctype in a Facelets template.

It's indeed unfortunate that Netbeans by default prepares the document with XHTML doctype while HTML5 is these days the recommended doctype. I don't do Netbeans, but in Eclipse you can easily edit those templates and even create your own. You can just replace the whole XHTML doctype by a HTML5 one. You can find/create those templates via Web » HTML Files » Editor » Templates in IDE prefs.

Please note that the HTML5 support in JSF 2.2 has got nothing to do with being able to support specifically the HTML5 doctype. On the contrary, this is supported on all JSF versions, even when legacy JSP is being used. JSP and Facelets are view technologies which allows you to generate HTML output, which can perfectly fine be HTML5 as good. This is also elaborated in the following closely related answer: Is it possible to use JSF+Facelets with HTML 4/5?

Instead, the HTML5 support in JSF 2.2 covers the possibility to define custom JSF component attributes and turning custom HTML elements into JSF components. This was not possible in JSF 2.1 and before. Any custom JSF component attributes (including the HTML5-recommended data-xxx attributes) were simply ignored by the default JSF renderers. See also the following related answer: Custom HTML tag attributes are not rendered by JSF. In JSF 2.2 you can easily specify custom attributes by the new http://xmlns.jcp.org/jsf/passthrough namespace as follows:

<html ... xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
...
<h:inputText ... a:autocorrect="off" />

This will end up in the by <h:inputText> unsupported attribute autocorrect to actually be included in the generated HTML output. Note that I use a XML namespace prefix of a ("attribute") instead of p as shown in the Java EE tutorial, as it would otherwise clash with default XML namespace prefix p of PrimeFaces.

Turning custom HTML elements (including HTML5 elements) into JSF components is a matter of specifying a jsf attribute such as jsf:id.

<html ... xmlns:jsf="http://xmlns.jcp.org/jsf">
...
<header jsf:id="header">...</header>
<main jsf:id="main">...</main>
<footer jsf:id="footer">...</footer>

Those will under the covers be turned into UIPanel (like as <h:panelGroup>). And yes, they are referencable in e.g. <f:ajax render>.

In other words, "HTML5 support" is just again another buzzword for "Custom attribute support".

Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?

The .jsf extension is where the FacesServlet is during the JSF 1.2 period often mapped on in the web.xml.

<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

The .xhtml extension is of the actual Facelets file as you've physically placed in the webcontent of your webapp, e.g. Webapp/WebContent/page.xhtml.

If you invoke this page with the .jsf extension, e.g. http://localhost:8080/webapp/page.jsf then the FacesServlet will be invoked, locate the page.xhtml file and parse/render its JSF components. If the FacesServlet isn't invoked, then the enduser would end up getting the raw XHTML source code (which can be seen by rightclick, View Source).

Sometimes a *.faces extension or /faces/* foldermapping is been used. But this was from back in the JSF 1.0/1.1 ages. You're free to choose and use whatever mapping you'd like to let FacesServlet listen on, even if it's a nothing-saying *.xyz. The actual page itself should always have the .xhtml extension, but this is configureable by the following <context-param> in web.xml:

<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xml</param-value>
</context-param>

This will change the FacesServlet to locate page.xml instad of (default) page.xhtml.

More recently, with JSF/Facelets 2.0 a *.xhtml mapping is been used. In JSF/Facelets 1.x it was not possible to use the same mapping extension as the physical file. It would result in an infinite loop. But since JSF/Facelets 2.0 it is possible and this allows you to call the page by http://localhost:8080/webapp/page.xhtml.

<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

This way you don't need to configure some security restrictions to hide the raw source files away for cases whenever the enduser changes for example .jsf in URL to .xhtml in browser address bar. Only tooling (IDEs and plugins) and learning resources still need to catch up the advocated move from *.jsf to *.xhtml. As per JSF 2.3, the FacesServlet will by default be autoregistered on *.xhtml too (next to /faces/*, *.faces and *.jsf). This is backported to Mojarra 2.2.11.

See also:

  • Can we use regular expressions in web.xml URL patterns?
  • Set default home page via <welcome-file> in JSF project
  • JSF returns blank/unparsed page with plain/raw XHTML/XML/EL source instead of rendered HTML output
  • What is the difference between creating JSF pages with .jsp or .xhtml or .jsf extension
  • Which XHTML files do I need to put in /WEB-INF and which not?
  • Customize FacesServlet <url-pattern> to get rid of .xhtml extension

JSF/Facelets: why is it not a good idea to mix JSF/Facelets with HTML tags?

During the JSF 1.0/1.1 ages this was indeed "not a good idea", because all the HTML was not automatically taken in the JSF component tree when using JSP as view technology. All plain HTML was eagerly by JSP rendered before the JSF component tree. E.g.

<p>Lorem ipsum <h:outputText value="#{bean.value1}"> dolor sit amet<p>
<p>Consectetur adipiscing <h:inputText value="#{bean.value2}" /> elit</p>

got rendered as

<p>Lorem ipsum dolor sit amet<p>
<p>Consectetur adipiscing elit</p>

value1
<input type="text" value="value2" />

To fix this you would need to bring <f:verbatim> in.

<f:verbatim><p>Lorem ipsum </f:verbatim><h:outputText value="#{bean.value1}"><f:verbatim> dolor sit amet<p></f:verbatim>
<f:verbatim><p>Consectetur adipiscing </f:verbatim><h:inputText value="#{bean.value2}" /><f:verbatim> elit</p></f:verbatim>

This was a real maintenance pain. This was one of the major reasons why JSF 1.0/1.1 was so hated.

Since JSF 1.2, with the new view handler, the <f:verbatim> was not necessary anymore. Developers can now breathe relieved. Moreover, the new view handler allowed JSF to use a different view technology than JSP and this way Facelets was born.

See also:

  • What are the main disadvantages of Java Server Faces 2.0?
  • Why Facelets is preferred over JSP as the view definition language from JSF2.0 onwards?
  • Is it possible to use JSF+Facelets with HTML 4/5?
  • JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used

Is it possible to use JSF+Facelets with HTML 4/5?

Since Facelets is a XML based view technology which eats and emits in essence XML markup, you cannot use it with a HTML4 doctype. The HTML4 doctype describes several elements which cannot be self-closing, like <link>, <meta>, <br> and <hr>. However, with XML you're forced to close them like <link/>, <meta/>, etc. So using a HTML4 doctype is absolutely not an option for Facelets (that is, when you respect the standards and/or fear the w3 validator, it will however work perfectly on the most if not all webbrowsers).

HTML5, on the other hand, allows XML markup. This is specified in chapter 3.2.2 - Elements:

Example:

<link type="text/css" href="style.css"/>

Authors may optionally choose to use this same syntax for void elements in the HTML syntax as well. Some authors also choose to include whitespace before the slash, however this is not necessary. (Using whitespace in that fashion is a convention inherited from the compatibility guidelines in XHTML 1.0, Appendix C.)

I myself use <!DOCTYPE html> all the way, also with JSF/Facelets, even without a <?xml?> declaration in top of the page. It works perfectly in all browsers. With a XHTML doctype you should as per the specification be using a Content-Type of application/xhtml+xml which would only make MSIE to choke (it doesn't understand it). And since that's still one of the most widely used browsers... Replacing the XHTML content type by text/html is considered harmful, you also don't want to do this.

As per your arguments:

HTML 5 do not support namespaces.

This doesn't matter. The namespaces are only of interest for the XML based server side view technology (like as Facelets) which in turn can generate pure HTML with those tags. The following example is legitimately valid for Facelets:

<!DOCTYPE html>
<html lang="en"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Title</title>
</h:head>
<h:body>
<h:outputText value="#{bean.text}" />
</h:body>
</html>

This renders legitimately valid HTML5 (for the client side):

<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
</head>
<body>
Some text
</body>
</html>

You see, Facelets already removes the XHTML declarations since they have no meaning in the client side.

And,

Also HTML 5 has some new elements that are not available in XHTML

this make also no sense. It's all about the generated output. Which can be HTML5 as good. Your only problem may be the browser support and the availability of 3rd party JSF components which renders HTML5 specific elements. Since JSF 2.2, it's possible to use the new passthrough elements feature to turn custom elements into a JSF component. Simply give the HTML5 element a jsf:id attribute. It'll transparently internally be interpreted as a UIPanel instance in the JSF component tree (like <h:panelGroup>).

<!DOCTYPE html>
<html lang="en"
xmlns:jsf="http://xmlns.jcp.org/jsf"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
>
<h:head>
<title>Title</title>
</h:head>
<h:body>
<header jsf:id="header">Header</header>
<nav jsf:id="nav">Nav</nav>
<main jsf:id="main">Main</main>
<footer jsf:id="footer">Footer</footer>
</h:body>
</html>

You can even reference it from ajax as in <f:ajax render="main">.

Actually, XHTML is overhyped. Its sole intent is to ease HTML development using XML based tools which can manipulate/transform/generate HTML pages on the server side (like as Facelets). But some starters also use it without using any XML tool and output it plain as-is, because it's "so cool" -for some unclear reason.

Don't get me wrong. XHTML is great as server side view technology. But simply not as client side markup technology. It has utterly no value at the client side.

See also:

  • Our XHTML wiki page
  • How should a <!DOCTYPE> section look in JSF? HTML5 or XHTML?
  • JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used

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

There are three main causes.

  1. FacesServlet is not invoked.
  2. XML namespace URIs are missing or wrong.
  3. Multiple JSF implemenations have been loaded.



1. Make sure that URL matches FacesServlet mapping

The URL of the link (the URL as you see in browser's address bar) has to match the <url-pattern> of the FacesServlet as definied in web.xml in order to get all the JSF works to run. The FacesServlet is the one responsible for parsing the XHTML file, collecting submitted form values, performing conversion/validation, updating models, invoking actions and generating HTML output. If you don't invoke the FacesServlet by URL, then all you would get (and see via rightclick, View Source in browser) is indeed the raw XHTML source code.

If the <url-pattern> is for example *.jsf, then the link should point to /register.jsf and not /register.xhtml. If it's for example /faces/*, like you have, then the link should point to /faces/register.xhtml and not /register.xhtml. One way to avoid this confusion is to just change the <url-pattern> from /faces/* to *.xhtml. The below is thus the ideal mapping:

<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>

If you can't change the <url-pattern> to *.xhtml for some reason, then you probably would also like to prevent endusers from directly accessing XHTML source code files by URL. In that case you can add a <security-constraint> on the <url-pattern> of *.xhtml with an empty <auth-constraint> in web.xml which prevents that:

<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>

JSF 2.3 which was introduced April 2017 has already solved all of above by automatically registering the FacesServlet on an URL pattern of *.xhtml during webapp's startup. The alternative is thus to simply upgrade to latest available JSF version which should be JSF 2.3 or higher. But ideally you should still explicitly register the FacesServlet on only one URL pattern of *.xhtml because having multiple possible URLs for exactly the same resource like /register.xhtml, /register.jsf, /register.faces and /faces/register.xhtml is bad for SEO.

See also:

  • Set default home page via <welcome-file> in JSF project
  • Opening JSF Facelets page shows "This XML file does not appear to have any style information associated with it."
  • Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?
  • JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used
  • Which XHTML files do I need to put in /WEB-INF and which not?
  • Our servlets wiki - to learn the mandatory basics about servlets


2. Make sure that XML namespaces match JSF version

Since introduction of JSF 2.2, another probable cause is that XML namespaces don't match the JSF version. The xmlns.jcp.org like below is new since JSF 2.2 and does not work in older JSF versions. The symptoms are almost the same as if the FacesServlet is not invoked.

<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">

If you can't upgrade to JSF 2.2 or higher, then you need to use the old java.sun.com XML namespaces instead:

<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">

But ideally you should always use the latest version where available.

See also:

  • Which XML namespace to use with JSF 2.2 and up
  • JSF tags not executed
  • Warning: This page calls for XML namespace http://xmlns.jcp.org/jsf/XXX declared with prefix XXX but no taglibrary exists for that namespace


3. Multiple JSF implementations have been loaded

One more probable cause is that multiple JSF implementations have been loaded by your webapp, conflicting and corrupting each other. For example, when your webapp's runtime classpath is polluted with multiple different versioned JSF libraries, or in the specific Mojarra 2.x + Tomcat 8.x combination, when there's an unnecessary ConfigureListener entry in webapp's web.xml causing it to be loaded twice.

<!-- 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>

When using Maven, make absolutely sure that you declare the dependencies the right way and that you understand dependency scopes. Importantingly, do not bundle dependencies in webapp when those are already provided by the target server.

See also:

  • Configuration of com.sun.faces.config.ConfigureListener
  • How to properly install and configure JSF libraries via Maven?


Make sure that you learn JSF the right way

JSF has a very steep learning curve for those unfamiliar with basic HTTP, HTML and Servlets. There are a lot of low quality resources on the Internet. Please ignore code snippet scraping sites maintained by amateurs with primary focus on advertisement income instead of on teaching, such as roseindia, tutorialspoint, javabeat, baeldung, etc. They are easily recognizable by disturbing advertising links/banners. Also please ignore resources dealing with jurassic JSF 1.x. They are easily recognizable by using JSP files instead of XHTML files. JSP as view technology was deprecated since JSF 2.0 at 2009 already.

To get started the right way, start at our JSF wiki page and order an authoritative book.

See also:

  • Java / Jakarta EE web development, where do I start and what skills do I need?
  • What is the need of JSF, when UI can be achieved with JavaScript libraries such as jQuery and AngularJS

How should a !DOCTYPE section look in JSF? HTML5 or XHTML?

That's the HTML5 doctype and it should work just fine in all browsers, including IE6.

JSF is officially specified to produce XHTML 1.0 compliant markup (with here and there only a few violations in the implementations which is fixed in JSF 2.2 and/or are manageable by context params). JSF can by design not produce non-XML sytnax (e.g. <br> instead of <br/>) and therefore the old HTML4 doctype is in no way compatible with JSF-produced HTML output (that is, when you respect the standards and/or fear the W3 validator; however, most if not all browsers are very forgiving on it). In contrary to the old HTML4 doctype, the HTML5 doctype allows XML syntax and is therefore compatible with XHTML doctypes. JSF pages can therefore be authored with HTML5 doctype.

The doctype is only of importance for how the webbrowser interprets and presents the HTML markup (as produced by JSF in your specific case, but the HTML does not necessarily need to be produced by JSF and thus browser's presentation is technically completely unrelated to JSF). Escpecially Microsoft IE has a major problem with certain doctypes or a complete lack of doctype. At the bottom of this page you can find a concise overview of browser behaviour in combination with certain doctypes. There are three standard behaviours:

  • Q - Quirksmode. You really don't want to have that. It triggers box model bug in IE. The CSS width and height then incorrectly covers the padding and border.
  • A - Almost standards mode. Affordable, only vertical sizing of table cells is not as per CSS2 spec. Useful if you want to avoid mysterious gaps of images in table cells.
  • S - Standards mode. Browser tries to be fully w3 HTML/CSS standard compliant. Preferred mode since it's the only mode you can be less or more certain that your website will look exactly the same in all browsers.

In your particular case, with the change from XHTML 1.0 transitional doctype to HTML5 doctype, Firefox, Chrome, Safari and IE>=8 will go from "A" to "S". So, you should definitely review the browser's presentation of your website as to padding of images in table cells if you intend a pixel-perfect design.

As to the importance of the doctype in IE, here's a piece of HTML which demonstrates the box model bug triggered by "Q" in IE6-9 (note that this does not manifest in IE10 anymore):

<!DOCTYPE html>
<html lang="en">
<head>
<title>Remove DOCTYPE to trigger quirksmode</title>
<style>
#box {
background: yellow;
width: 100px;
padding: 20px;
border: 20px solid black;
margin: 20px;
}
</style>
</head>
<body>
<div id="box">box</div>
</body>
</html>

Copy'n'paste'n'run it. With <!DOCTYPE html> present, you'll see a rectangle. Without the doctype line you'll see a genuine square (in IE10 you need in the webdeveloper toolset (press F12) to change the "Browser mode" to e.g. IE9 in order to see it).

Sample Image

See also:

  • JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used
  • Is it possible to use JSF+Facelets with HTML 4/5?
  • Should I start with HTML or XHTML?

HTML5 Pass-Through element causes Eclipse warning 'Unknown tag'

This is not a JSF problem. You would still have exactly the same problem when removing the passthrough element trigger jsf:id. You would even still have exactly the same problem when not using JSF tags/attributes anywhere in the XHTML file.

The <main> tag is relatively new in HTML5 (it was only added in HTML5 CR of August 2013). Other HTML5 tags currently in your XHTML document already exist longer (far back in 2008). Eclipse simply doesn't recognize <main> as a tag registered in the default XML namespace as identified by http://www.w3.org/1999/xhtml. Eclipse holds an internal list of registered tags. If upgrading to latest Eclipse (SR) version doesn't solve the problem, then your best bet is to report this as an issue to Eclipse guys. In the meanwhile, just choose the quick fix option "Ignore 'main' element in HTML5 validation".


Unrelated to the concrete problem, that XML prolog doesn't belong there. Get rid of it. Further I also wonder the necessity of the "header", "nav", "main" and "footer" being whole JSF components. I'm not really seeing any useful real world appliances with this. You'd most likely as good just keep them plain HTML. This saves you from unnecessary overhead.

See also:

  • XML prolog / instruction not removed from XHTML output
  • JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used


Related Topics



Leave a reply



Submit