This question was asked on Stack Overflow more than 12 years ago, and the answer was "No". Today, JSP is considered a deprecated technology, and Facelets has replaced it.
However, my application is not a Jakarta Faces application. It is an action-based MVC application using Jakarta Servlet components. I want to use Facelets as the template engine, but I couldn't find any guides or online resources on setting it up in a Jakarta Servlet web application.
Any comments?
It looks like there's some confusion. Jakarta Pages, formerly known as JSP, is not deprecated in context of the Jakarta EE platform. Jakarta Pages is only deprecated in context of being a supported "view technology" for the MVC framework Jakarta Faces. See also among others Why Facelets is preferred over JSP as the view definition language from JSF 2.0 onwards?
This basically boils down to that since version 2.0 the Jakarta Faces MVC framework, formerly known as JSF, will not anymore introduce new tags/components for use with Jakarta Pages view technology. For example, the in JSF 2.0 introduced <f:ajax>
tag is only available for Facelets, not for JSP. And since version 4.0 the Jakarta Faces MVC framework has removed all support for using JSP as view technology, hereby reducing no less than 500KB in JAR file size.
You can just continue using Jakarta Pages view technology for "plain vanilla Servlets", Jakarta Rest, Jakarta MVC or whatever (homegrown) action based MVC framework you're using.
I want to use Facelets as the template engine, but I couldn't find any guides or online resources on setting it up in a Jakarta Servlet web application.
You can however of course use Facelets view technology instead. You only need to understand that the FacesServlet
is basically also a servlet which supports the Facelets view technology and is capable of managing the Facelets compiler on them. Simply register it as documented in Jakarta Servlet deployment descriptor file /WEB-INF/web.xml
:
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
No, the Jakarta Faces deployment descriptor file /WEB-INF/faces-config.xml
is not needed. You however do need the Jakarta CDI deployment descriptor file /WEB-INF/beans.xml
as Jakarta Faces won't launch without CDI.
And simply hide away the *.xhtml
files into /WEB-INF
folder to prevent them from being accessed directly as if they were Jakarta Faces pages. Basically the same "best practice" you should be doing with Jakarta Pages as well. See also doGet and doPost in Servlets. Also you need to restrict to using exclusively <ui:xxx>
tags of Facelets and thus not <h:xxx>
/<f:xxx>
tags (which are part of Jakarta Faces).
Here's a kickoff example:
src
`-- main
|-- java
| `-- com
| `-- example
| `-- YourServlet.java
|-- resources
`-- webapp
`-- WEB-INF
|-- pages
| |-- example.xhtml
| `-- include.xhtml
|-- beans.xml
`-- web.xml
example.xhtml
:
<!DOCTYPE html>
<html lang="en" xmlns:ui="jakarta.faces.facelets">
<head>
<title>Page title</title>
</head>
<body>
<h1>Content from example.xhtml</h1>
<ui:include src="include.xhtml" />
</body>
</html>
include.xhtml
:
<ui:composition xmlns:ui="jakarta.faces.facelets">
<p>content from include.xhtml</p>
</ui:composition>
YourServlet.java
:
@WebServlet("/example")
public class ExampleServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/pages/example.xhtml").forward(request, response);
}
}
Open it at http://localhost:8080/projectname/example
:
And here you can find an example of <ui:composition template>
approach: How to include another XHTML in XHTML using JSF 2.0 Facelets?