tags:

views:

1455

answers:

1

Hi all,

I've got an JSP tag that I would like to use in my JSF/Seam application. Could someone please give me some guidance in getting my environment to accept the tag. Can I just point a faclets *.taglib.xml file at my old tag or do I need to write a component extending the previous tag perhaps?

Cheers for any info, Lee

+2  A: 

I would be very reluctant to try and directly invoke a JSP tag outside a JSP context. As the documentation points out, the similarities between JSP and Facelets are pretty superficial.

One hack (I suspect that any solution is going to be a hack) might be to include the JSP by casting down to the servlet API.

This function includes a given resource using a RequestDispatcher:

public class Includer {

  public static String include(String resource) {
    FacesContext context = FacesContext
        .getCurrentInstance();
    ExternalContext ext = context.getExternalContext();
    include(ext.getContext(), ext.getRequest(), ext
        .getResponse(), resource);
    return "";
  }

  private static void include(Object context,
      Object request, Object response, String resource) {
    ServletContext servletContext = (ServletContext) context;
    ServletRequest servletRequest = (ServletRequest) request;
    ServletResponse servletResponse = (ServletResponse) response;
    RequestDispatcher dispatcher = servletContext
        .getRequestDispatcher(resource);
    try {
      dispatcher.include(servletRequest, servletResponse);
    } catch (IOException e) {
      throw new FacesException(e);
    } catch (ServletException e) {
      throw new FacesException(e);
    }
  }

}

This function is defined in a Facelet taglib file WEB-INF/facelets/include.taglib.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
  "http://java.sun.com/dtd/facelet-taglib_1_0.dtd"&gt;
<facelet-taglib xmlns="http://java.sun.com/JSF/Facelet"&gt;
  <namespace>http://demo&lt;/namespace&gt;
  <function>
    <function-name>include</function-name>
    <function-class>inc.Includer</function-class>
    <function-signature>
      java.lang.String include(java.lang.String)
    </function-signature>
  </function>
</facelet-taglib>

This is specified as a library in the WEB-INF/web.xml using a context parameter:

  <context-param>
    <param-name>facelets.LIBRARIES</param-name>
    <param-value>/WEB-INF/facelets/include.taglib.xml</param-value>
  </context-param>


Example usage

JSP to be included, includeme.jsp:

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
  <jsp:directive.page language="java"
    contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" />
  <b>Some data: ${foo}</b>
</jsp:root>

Facelet that includes the JSP:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:demo="http://demo"&gt;
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JSP include hack</title>
</head>
<body>
<h:form>
  <p> ${demo:include('/includeme.jsp')} </p>
  <h:inputText type="text" value="#{foo}" />
  <h:commandButton type="submit" />
</h:form>
</body>
</html>

Note the use of ${demo:include('/includeme.jsp')} to invoke the request dispatcher (the function returns an empty String). The function is included by the attribute xmlns:demo="http://demo". The request scope variable foo is bound to the text field and picked up by the JSP.


All I can say about this is that it worked for me and there are probably a dozen reasons why it wouldn't work with a certain combination of tags, or with certain combinations of JSF libraries. Caveat emptor.

McDowell
Thanks for the answer. Looks like I'm just going to have to take the hit and create JSF as components well.
Lee Theobald
When I try to get the requestDispatcher in Icefaces I get an Unsupported exception....is there another way of getting it
DD