Issue
I'd like to include a servlet generated content in a facelet using ui:include. So far I only got errors.
Note that the servlet works fine, GET requests from a browser are ok.
Note that I can successfully include content from another facelet file, but not when the content is servlet generated.
I googled and stackoverflowed my issue but could not find matching responses.
myfacelet.xhtml (at the root of the webapp, i.e. reached by "http://localhost:8080/mywebapp/myfacelet.xhtml"):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>JSF Dynamic Content</title>
</h:head><h:body>
<h3>Dynamic content:</h3>
<ui:include src="dynamic-content"/>
</h:body>
</html>
MyServlet.java (can be reached by "http://localhost:8080/mywebapp/dynamic-content"):
@WebServlet(name = "DynamicContentServlet", urlPatterns = {"/dynamic-content"})
public class DynamicContentServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.println("<p>Dynamic stuff</p>");
}
}
web.xml (JSF related stuff only) :
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FacesServlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.jsf</url-pattern>
<url-pattern>*.faces</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
For ui:include="/dynamic-content" and urlPatterns="/dynamic-content" (or ui:include="/mywebapp/dynamic-content" and urlPatterns="/dynamic-content") the error is:
javax.faces.view.facelets.TagAttributeException: /myfacelet.xhtml @12,48 <ui:include src="/dynamic-content"> Invalid path : /dynamic-content
at com.sun.faces.facelets.tag.ui.IncludeHandler.apply(IncludeHandler.java:152)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:195)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:86)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:774)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:100)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
(...)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
at java.lang.Thread.run(Thread.java:662)
For ui:include="dynamic-content" and urlPatterns="/dynamic-content" or ui:include="dynamic-content.bla" and urlPatterns="*.bla", the error is:
java.io.FileNotFoundException
at org.apache.naming.resources.DirContextURLConnection.getInputStream(DirContextURLConnection.java:369)
at com.sun.faces.facelets.impl.DefaultFaceletCache._getLastModified(DefaultFaceletCache.java:172)
at com.sun.faces.facelets.impl.DefaultFaceletCache.access$000(DefaultFaceletCache.java:62)
at com.sun.faces.facelets.impl.DefaultFaceletCache$1.newInstance(DefaultFaceletCache.java:82)
at com.sun.faces.facelets.impl.DefaultFaceletCache$1.newInstance(DefaultFaceletCache.java:78)
at com.sun.faces.util.ExpiringConcurrentCache$1.call(ExpiringConcurrentCache.java:99)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at com.sun.faces.util.ExpiringConcurrentCache.get(ExpiringConcurrentCache.java:114)
at com.sun.faces.facelets.impl.DefaultFaceletCache.getFacelet(DefaultFaceletCache.java:121)
at com.sun.faces.facelets.impl.DefaultFaceletCache.getFacelet(DefaultFaceletCache.java:62)
at com.sun.faces.facelets.impl.DefaultFaceletFactory.getFacelet(DefaultFaceletFactory.java:256)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:366)
at com.sun.faces.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:346)
at com.sun.faces.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:199)
at com.sun.faces.facelets.tag.ui.IncludeHandler.apply(IncludeHandler.java:147)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:137)
at com.sun.faces.facelets.tag.jsf.ComponentTagHandlerDelegateImpl.apply(ComponentTagHandlerDelegateImpl.java:195)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:120)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:86)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.buildView(FaceletViewHandlingStrategy.java:774)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:100)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
(...)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
at java.lang.Thread.run(Thread.java:662)
Also note that the servlet never gets executed.
What is wrong with my code?
Is the include possible?
How can I achieve it?
Best regards
Solution
The <ui:include>
can only include another Facelets file, not the output of a JSP/Servlet.
You'd either need to replace the Servlet by a fullworthy Facelets file, or to use a Facelets tag file or a Facelets composite component wherein the HTML can also be generated dynamically using JSTL tags or the rendered
attribute, if necessary with help of a backing bean or a backing component.
If you absolutely need to use a Servlet for some reason, for example because you're in a migration process from legacy JSP/Servlet to JSF/Facelets and don't have much time left to properly transform to the Servlet to a sane Facelets approach, then you can also consider to use <o:resourceInclude>
component of OmniFaces:
<o:resourceInclude path="/dynamic-content" />
But as said, this isn't the right design approach. For a proper long term solution, you should look into replacing the Servlet by a Facelets file/tag/composite.
Answered By - BalusC