The Source for Java Technology Collaboration


Facelets Wiki Home

Does Facelets support JSR-168 portlets?

Yes, since JSF in general does. Certain components (e.g. some that use javascript) might not. You should put <ui:composition> around your content so that your portlet doesn't generate html/body tags. Also, I think you can define your xml namespaces on any root element, so you can skip html/head and just use <f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"> ...

How can I use ADF and Facelets together?

You need to install the FaceletViewHandler using:

 <context-param>
   <param-name>oracle.adf.view.faces.ALTERNATE_VIEW_HANDLER</param-name>
   <param-value>com.sun.facelets.FaceletViewHandler</param-value>
 </context-param>

in WEB-INF/web.xml, not in faces-config.xml.

What's the difference between c:forEach and ui:repeat?

c:forEach is a "compile-time" loop (happens once per page, and duplicates component tags) and ui:repeat is similar to the MyFaces Tomahawk t:dataList component as a render-time loop (happens once per request and components inside the list exist only once -- flyweight pattern). Generally, you want to use a render-time loop, not a compile-time loop. The only time you want to use c:forEach or c:if logic is when you want to do something you can't do with a render-time loop, such as dynamically adjusting the number of columns in a dataTable.

The technical differences can be fairly dramatic. Lets say you are iterating over 5,000 items in a list, with c:forEach, you'll end up with 5,000 * the number of child components. This could mean your tree now has 15,000 components in a generation, each with it's own set of state. With ui:repeat, h:dataTable, t:dataList, etc-- these 5,000 items are only represented at the time of rendering, leaving you with a single set of children. Basically, your outputText or input instances are just re-evaluated 5,000 times. StateSaving? wise, they are also more efficient since between each iteration, it only saves values for those components which are inputs. If you are simply outputting data (no inputs), your StateSize? shouldn't group by N times.

What's the difference between using h:outputText v. just the EL, e.g. #{foo) ?

It's a matter of preference, but Facelets takes all of the stuff between your JSF components, including HTML tags and inlined EL and compiles them as transient components. So they don't add anything to the view state overhead, but they are able to properly participate in the component model for rendering.

(Posted by Craig McClanahan) Actually, there is one important difference. By default, the h:outputText component escapes dangerous characters in HTML, such as a left angle bracket ('<'), while using a plain EL expression does not. Without escaping (or ensuring that such characters do not exist in your model data), your application might be vulnerable to cross site scripting attacks.

Why are my attributes not set in my component ?

(Composed by Tom Baeyens based on https://facelets.dev.java.net/servlets/BrowseList?list=users&by=thread&from=386702 )

The basics about UIComponents and tags can be found in the facelet docs in section UIComponent: https://facelets.dev.java.net/nonav/docs/dev/docbook.html#taglib-create-component

There are different ways in obtaining the tag attribute value in your component. But a plain getter-setter property implementation won't do it.

In JSF 1.1, you have to implement your property foo like this

private String foo = null;
public String getFoo() {
  if (this.foo != null) return this.foo;
  ValueBinding vb = this.getValueBinding("foo");
  if (vb != null) return (String) vb.getValue(faces);
  return null;
}
public void setFoo(String foo) {
  this.foo = foo;
}

In JSF 1.2, ValueBinding becomes ValueExpression and the getter changes a bit

private String foo = null;
public String getFoo() {
  if (this.foo != null) return this.foo;
  ValueExpression ve = this.getValueExpression("foo");
  if (ve != null) return (String) ve.getValue(faces.getELContext());
  return null;
}
public void setFoo(String foo) {
  this.foo = foo;
}

alternatives are using getAttributes() within your renderer or overriding the setValueBinding in your component like this

public void setValueBinding(String name, ValueBinding valueBinding) {
  if ("foo".equals(name)) {
    this.foo = valueBinding.get(getFacesContext());
  }
}

I'm getting Duplicate ID Errors (and Bindings)

This can be caused by a couple things. The first is when you use JSTL or logical predicates in your templates which add or remove components based on some volatile logic in your model. It's not so much the case that your component tree can't change between requests, but you do open opportunities for errors to occur. Sometimes explicitly providing id's to your components corrects this problem such that JSF has no way of accidentally assigning a duplicate.

The second way this can happen is when you using 'binding' attributes on your components. If you are binding components to anything other than request-scope, you can run into problems where components, and their assigned identifiers, get injected into another page, conflicting with their identifiers. Again, you can attempt to provide explicit id's to your components to avoid conflict and guarantee uniqueness, but it doesn't fix the greater issue with application/session scoped bindings:

1) UIComponents are not Serializable-- and therefore cannot be clustered

2) UIComponents are not thread safe can cannot be used by multiple requests at once

Binding UIComponents to backing beans is actually something worth doing to ease particular use cases. Instead of using a session/application scoped bean, use a request-scoped composite mediator that receives your session beans and the UIComponent instance to coordinate behavior. The injection of your session-scoped beans can be managed with the faces-config managed-property or with any of the 3rd party extensions such as Spring 2.0 or Seam.

How do I use Facelets and JSP in the same application?

You have to use prefix mapping for the Facelets pages in order for this to work. Leave the DEFAULT_SUFFIX with the JSF default of .jsp. Configure the Facelet's VIEW_MAPPINGS parameter:

<web-app>
  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.jsp</param-value>
  </context-param>

  <!-- Facelets pages will use the .xhtml extension -->
  <context-param>
    <param-name>facelets.VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
  </context-param>     

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  </servlet>
 
  <!-- Use prefix mapping for Facelets pages, e.g. http://localhost:8080/webapp/faces/mypage.xhtml -->
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
</web-app>

Facelets 1.1.11 comes with jars for both Mojarra (JSF RI 1.2) and MyFaces (JSF 1.1) so which one am I running?

The classloader determines which version you are running. The best decision is to remove the files from the version you do not need.

To use the Sun JSF 1.2 RI, simply remove the WEB-INF/lib files myfaces-api-1.1.3-SNAPSHOT.jar and myfaces-impl-1.1.3-SNAPSHOT.jar.

To use the MyFaces JSF 1.1 (MyFaces version 1.1.3 in Facelets 1.1.11) you must remove the WEB-INF/lib files jsf-api.jar and jsf-impl.jar and then download the Apache Jakarta Commons Codec (version 1.3 works) jar file and put it into WEB-INF/lib. The Codec is required by MyFaces to perform (URL) Base64 encoding and decoding. To download the "Commons Codec" see http://jakarta.apache.org/commons/codec. These (Myfaces) changes have been used to make Facelets v1.1.11 run under Tomcat 5.5.16 with MyFaces release 1.1.3

What does "Re: SEVERE: Error listenerStart " mean?

If your log file shows this error:

> SEVERE: Exception sending context initialized event to listener instance of class com.sun.faces.config.GlassFishConfigureListener
> java.lang.NoSuchMethodError: javax.servlet.ServletContext.getContextPath()Ljava/lang/String;

Then it indicates you are using the Sun RI v1.2 or higher on a container or application server which does not support the Servlet Spec v2.5 or above. An example is Tomcat 5.5 which only supports Servlet v2.4.

Why doesn't my &bull; / &Aring; / &amp; render in the output?

Facelets 1.1.11 does escaping properly (earlier versions are broken), but only supports the character entities built into XML: &amp; &lt; &gt; &apos; &quot;

You must use the numeric entities for &bull; &Aring;, etc.

How do I insert a non-breaking space?

use &#160;

Alternately, use <f:verbatim>&amp;nbsp;</f:verbatim>

How do I prevent HTML comments from being rendered?

Add the following to your web.xml:
  <context-param>
    <param-name>facelets.SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
  </context-param>

Why doesn't my c:if / ui:repeat / ui:include work properly?

You're probably using a bad combination of build-time and render-time tags. For example, c:if is a build-time tag, so any EL expressions are only evaluated once (when the tree is built), even if you put it inside a ui:repeat or h:dataTable. Conversly, since ui:repeat is a 'render-time tag' (i.e. a UIComponent), you can't use it to iterate over build-time tags such as f:selectItem.

Build-time (facelet) tags:

  • all JSTL tags (e.g. c:if, c:forEach, c:choose)
  • all ui tags except ui:repeat (e.g. ui:include, ui:decorate, ui:composition)
  • all core faces tags except f:verbatim (e.g. f:validator, f:convertNumber, f:selectItem)

Render-time tags (UIComponents):

  • all UIComponent tags (e.g. ui:repeat, h:inputText, t:saveState)

See also http://www.ninthavenue.com.au/blog/c:foreach-vs-ui:repeat-in-facelets

Is Facelets in ibiblio or another Maven repository?

Yes it is now in the ibiblio repository.

groupId : com.sun.facelets

artifactId: jsf-facelets

It is also in the java.net Maven repository: https://maven-repository.dev.java.net/repository/

In the pom:

<repositories>
              <repository>
                        <id>dev.java.net</id>
                        <name>dev.java.net-repo </name>
                        <url>https://maven-repository.dev.java.net/repository/</url>
                        <layout>legacy</layout> 
                </repository>

</repositories>

Can I pass a MethodBinding to a template?

No, you can only pass a value binding to a template.

One workaround is to pass the bean as a ValueBinding and hardcode the method name in your template (example needed here).

Another is to pass the bean as a ValueBinding and pass the method as a ValueBinding (example needed here).

Rick Hightower has an example in his article on Facelets. His template uses this code to render a commandLink:

<h:commandLink id="#{action}" value="#{label}" 
                                     action="#{backingBean[action]}"/>

And he calls the template like this:

<a:columnCommand label="Edit" action="editCD" 
backingBean="${CDManagerBean}"/>

There is also an article that discusses using a custom ComponentHandler to pass method bindings.

http://andrewfacelets.blogspot.com/2006/06/creating-composite-controls-with-jsf.html

The el-jars from the newest facelets-distro require java 5. Where do I find el-jars that work with JDK 1.4?

Use the two jar-files from facelets-1.0.1.

How do I change the response contentType?

<f:view contentType="application/rss+xml"> ... </f:view>

I'm getting a java.lang.IllegalStateException, instead of the Facelets debug screen

You get this exception because some error occurred, and Facelets tries to render the debug screen, but a part of the rendered output were already send to the client. This happens if the Facelets response writer fills up and is thus flushed and send to the client BEFORE the debug output method was invoked.

When part of the rendered output is send to the client, the isCommitted() method of HttpServletResponse will return true and it will not be possible to call HttpServletResonse methods such as reset() or sendRedirect(). These methods are called during generation of the Facelets debug screen.

A response writer will fill up if your (x)html output is larger than the "default" response buffer size, which is may easily be to small. The solution is to increase the web context parameter facelets.BUFFER_SIZE to a sufficiently large value. See the documentation for more information on this parameter.

I'm getting a java.lang.IllegalStateException, instead of my (web.xml) error page

See above

How do I use the JSF 1.2 beforePhase or afterPhase attributesinside of Facelets compositions?

Two things. Fist, in Facelets 1.14 or earlier, the attribute "beforePhase" is misnamed "beforePhaseListener" (same goes for afterPhase). This issue [[http://facelets.dev.java.net/issues/show_bug.cgi?id=294] [294]].

Second, make sure you use this tag with or instead of or :

<f:view beforePhaseListener="#{myBean.myPhaseListenerMethod}">
    <ui:decorate template="/WEB-INF/templates/template.xhtml">
        ....
    </ui:decorate>
</f:view>
This ensures that markup above and below the composition-related tag isn't trimmed.

Why can't I use {JSP Tag library name here} with Facelets?

Facelets is a completely different View technology than JSP. Facelets don't use the Servlet heirarchy for rendering the view. A Facelet doesn't get compiled into a JspServlet?.

All tag libraries written before Facelets came into existence, were written for and using JSP technology. Which means that unless you have a Facelets implementation of the same tag, the tag won't work. Newer tag libraries often ship with a Facelets implementation too, so contact the maintainer of your tag library, and ask for it. Or write it yourself!

Topic FaceletsFAQ . { Edit | Ref-By | Printable | Diffs r27 < r26 < r25 < r24 < r23 | More }
 XML java.net RSS

Revision r27 - 27 Jun 2008 - 06:48:06 - Main.rajeshja
Parents: Facelets