Wednesday, 7 November 2007

JSF Passing parameters to included jsp pages

The question was brought up in the JDeveloper forum. When I started creating my first JSF pages I wanted to be able to create a menu that I could edit and make make the changes propagate to all pages immediately. So What I wanted back then was amethod to include a jsp to all my pages but also be able to pass parameters from the including page to the one being included.

The answer came from the book Mastering JavaServer Faces by Bill Dudney, Jonathan Lehr, Bill Willis and LeRoy Mattingly.

The approach is to create a subview and then include the page using a jsp:include tag. Inside the include you must use a jsp:param tag where you define the name and value of the expected JSP parameter. To cut the long story short, I tested the solution with JDeveloper and here is the code fragment to use.

            <f:subview id="header">
                <jsp:include page="/header.jsp" flush="true">
                    <jsp:param name="pageTitle" value="Welcome to my first JSF Application"/>

The included page should be surrounded by an f:subview tag. The external parameter can be accessed by an EL expression like "#{param.paramName}" and a simple example would be something like :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<%@ page contentType="text/html;charset=ISO-8859-7"%>
<%@ taglib uri="" prefix="f"%>
<%@ taglib uri="" prefix="af"%>
<%@ taglib uri="" prefix="afh"%>
<f:subview id="header">
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-7"/>
      <af:panelHeader text="#{param.pageTitle}"/>      

... and one last comment. I guess that this is the first time that the Copy as HTML command works correctly in JDeveloper on Linux. :-)


david.karr said...

I tried this arrangement (JSF 1.1, RichFaces 3.1.3, WebLogic 9.2.2), but I got a very unhelpful exception:

javax.faces.FacesException: Assertion Failed
at com.sun.faces.util.Util.doAssert(
at com.sun.faces.taglib.jsf_core.ViewTag.getComponentType(
at javax.faces.webapp.UIComponentTag.createComponent(
at javax.faces.webapp.UIComponentTag.createChild(
at javax.faces.webapp.UIComponentTag.findComponent(
at javax.faces.webapp.UIComponentTag.doStartTag(
at com.sun.faces.taglib.jsf_core.ViewTag.doStartTag(

david.karr said...

Just to add a little more info: From what I can tell, the "getComponentType()" method just does this:

throw new IllegalStateException();

So I guess there's an assumption that a subclass is supposed to be providing real functionality. I'm not sure why this would be happening.

david.karr said...

Oh, ok, never mind. It appears the included page has to use "f:subview", not "f:view".

However, I also see that variable references in the included page no longer work. I get errors like:

Error testing property 'propertyID' in bean of type null

(the references were working before moving them to the included page.)

shane said...

Thank you very much for the info...