1

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

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for the answer. I may open a dedicated question to get proper design information. For now I focus on the "include servlet generated content" issue. :) I could not find technical information about this "ui:include" limitation. I even found sources that state that it is possible. :/ Do you have sources/explanations/specs about the limitation?
That's one of the sources I refer to. From this documentation I understand that any XHTML file can be included, not just facelets. :'(
"There are three things this tag can include: plain XHTML, and XHTML pages that have either a composition tag or a component tag." A servlet is not among them.
I used 'ui:include src="localhost:8080/mywebapp/dynamic-content"'. Now it works, the inclusion is executed! There is something really fishy in "ui:include". I suspect that for relative (such as "bla/bli.xhtml") or absolute (such as "/bla/bli.xhtml") URLs, JSF checks if the target URL is an existing facelet (if not, then error). On the other hand, for "full" URL (such as "host:port/app/bla/bli") it does not, and the inclusion just works. What do you think? Best regards.
|
0

I too am developing an app that must perform dynamic page generation including embedded images, <map> and <area> tags and associated <div> tags which highlight on rollover.

My naive first test approach was to just write out the entire html from a StringBuffer: response.getWriter().println(sb.toString());. This worked, but it's a hack, and does not take advantage of my JSF template. Nor does it use the template even if I write out an entire <ui:composition> element.

In the Java EE 6 tutorial, there is detailed information on how to create a custom component. See here: http://docs.oracle.com/javaee/6/tutorial/doc/glpcb.html

This seems to support BalusC's comment above, "...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."

Your mileage may vary!

Comments

0

It has bean a while since the question is posted, but someone may find it useful, and I welcome your corrections if I did something stupid! I encountered the same issue, I solved it with a workout through javascript, the clues I used was from this link https://www.w3schools.com/howto/howto_html_include.asp , my servlet was to generate a map tag dynamically and it was set up on (web.xml) file with servlet filter (contours), so I applied the link in xhtml using the javascript from above mentioned link, (note: the rtutil.appUrl returns the context path of my JSF applicaiton), I applied it as follows:

<div w3-include-html="#{rtutil.appUrl}/contours/map"></div> <script type="text/javascript" src="resources/js/rtscript.js"></script> <script type="text/javascript"> includeHTML(); $(document).ready(function () { cityplanmap(); }); </script> 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.