4 Replies Latest reply on Jun 26, 2007 8:18 PM by David Radunz

    Using facelets in .xml files

    Glenn Marcus Newbie

      Seam 1.2.1 on JBoss 4.0.5

      Similar to the blog example, I would like to use a .xml file with facelet tags to dynamically generate a valid xml HTTP response. When I call the .xml file, I just get the contents of the file without it being processed by Facelets:


      Here is my web.xml file:

      <?xml version="1.0" ?>
      <web-app xmlns="http://java.sun.com/xml/ns/j2ee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
       version="2.4">
      
       <!-- Ajax4jsf (must come first!) -->
      
       <filter>
       <display-name>Ajax4jsf Filter</display-name>
       <filter-name>ajax4jsf</filter-name>
       <filter-class>org.ajax4jsf.Filter</filter-class>
       </filter>
      
       <filter-mapping>
       <filter-name>ajax4jsf</filter-name>
       <url-pattern>*.seam</url-pattern>
       </filter-mapping>
      
       <context-param>
       <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
       <param-value>org.jboss.seam.ui.facelet.SeamFaceletViewHandler</param-value>
       </context-param>
      
       <!-- Seam -->
      
       <listener>
       <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
       </listener>
      
       <filter>
       <filter-name>Seam Filter</filter-name>
       <filter-class>org.jboss.seam.web.SeamFilter</filter-class>
       </filter>
      
       <filter-mapping>
       <filter-name>Seam Filter</filter-name>
       <url-pattern>/*</url-pattern>
       </filter-mapping>
      
       <servlet>
       <servlet-name>Seam Resource Servlet</servlet-name>
       <servlet-class>org.jboss.seam.servlet.ResourceServlet</servlet-class>
       </servlet>
      
       <servlet-mapping>
       <servlet-name>Seam Resource Servlet</servlet-name>
       <url-pattern>/seam/resource/*</url-pattern>
       </servlet-mapping>
      
       <!-- MyFaces -->
      
       <listener>
       <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
       </listener>
      
       <!-- Facelets development mode (disable in production) -->
      
       <context-param>
       <param-name>facelets.DEVELOPMENT</param-name>
       <param-value>true</param-value>
       </context-param>
      
       <context-param>
       <param-name>facelets.SKIP_COMMENTS</param-name>
       <param-value>true</param-value>
       </context-param>
      
      
       <!-- JSF -->
      
       <context-param>
       <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
       <param-value>client</param-value>
       </context-param>
      
       <context-param>
       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
       <param-value>.xhtml</param-value>
       </context-param>
      
       <servlet>
       <servlet-name>Faces Servlet</servlet-name>
       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
       <load-on-startup>1</load-on-startup>
       </servlet>
      
       <servlet-mapping>
       <servlet-name>Faces Servlet</servlet-name>
       <url-pattern>*.seam</url-pattern>
       </servlet-mapping>
      
       <security-constraint>
       <display-name>Restrict raw XHTML Documents</display-name>
       <web-resource-collection>
       <web-resource-name>XHTML</web-resource-name>
       <url-pattern>*.xhtml</url-pattern>
       </web-resource-collection>
       <auth-constraint>
       <role-name>NONE</role-name>
       </auth-constraint>
       </security-constraint>
      
      </web-app>
      


      and here is my .xml file:
      <?xml version="1.0" ?>
      <events xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:s="http://jboss.com/products/seam/taglib">
      
      
      <ui:component>
      <f:view contentType="text/xml">
      <data
       wiki-url="#{basepath}"
       wiki-section="first attempt"
       >
      
       <ui:repeat value="#{goals}" var="g">
       <event start="#{g.formattedDate}" title="#{g.title}">
       <h:outputText value="#{g.text}"/>
       </event>
       </ui:repeat>
      
      </data>
      </f:view>
      </ui:component>
      </events>
      


        • 1. Re: Using facelets in .xml files
          Pete Muir Master

          Just to check you are calling it as /path/to/file.seam

          • 2. Re: Using facelets in .xml files
            Glenn Marcus Newbie

            The file is called goals.xml

            If I call it directly from the browser, I get the unprocessed xml.

            If I call it with goals.seam, I get a 404 error.

            If I rename goals.xml to goals.xhtml, it gets processed by facelets and returns the correct data.

            Why does a .xml file work in the blogexample, and not in my project?

            • 3. Re: Using facelets in .xml files
              Pete Muir Master

              The blog example uses prefix mapping to the Faces Servlet, you are using extension mapping.

              • 4. Re: Using facelets in .xml files
                David Radunz Newbie

                The following defines what file extension to look up:

                <context-param>
                 <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
                 <param-value>.xhtml</param-value>
                 </context-param>


                And the following defined what extension to provide in the URL to match the .xhtml file:

                <filter-mapping>
                 <filter-name>ajax4jsf</filter-name>
                 <url-pattern>*.seam</url-pattern>
                 </filter-mapping>


                Based on this, it would appear that you can have multiple definitions for the URL extension to map as it's a filter. But you can only map these to one extension to look up - unless you do some fancy stuff like overload the ViewHandler (http://www.nabble.com/mixing-clay-full-html-and-full-xml-views-t2070241.html).

                So, to make it prettier; Define two entry point extension to provide in the URL to match the .xhtml file:

                 <filter-mapping>
                 <filter-name>ajax4jsf</filter-name>
                 <url-pattern>*.seam</url-pattern>
                 </filter-mapping>
                
                 <filter-mapping>
                 <filter-name>ajax4jsf</filter-name>
                 <url-pattern>*.xml</url-pattern>
                 </filter-mapping>
                
                 <context-param>
                 <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
                 <param-value>.xhtml</param-value>
                 </context-param>
                


                Then make a request to http://localhost:8080/context/goals.xml which will render a file named "goals.xhtml".


                Cheers,

                David